v1.0: 实现了ATPG全流程
This commit is contained in:
parent
535cc3bd81
commit
ba70167a6b
BIN
.nfs00000000073d9db3000000b1
Executable file
BIN
.nfs00000000073d9db3000000b1
Executable file
Binary file not shown.
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@ -9,12 +9,12 @@
|
|||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/atpg",
|
"program": "${workspaceFolder}/atpg",
|
||||||
"args": ["${workspaceFolder}/benchmark/c432.bench"],
|
"args": ["-i", "${workspaceFolder}/benchmark/c17.bench"],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${fileDirname}",
|
"cwd": "${fileDirname}",
|
||||||
"environment": [],
|
"environment": [],
|
||||||
"externalConsole": false,
|
"externalConsole": false,
|
||||||
"MIMode": "lldb",
|
"MIMode": "gdb",
|
||||||
"setupCommands": [
|
"setupCommands": [
|
||||||
{
|
{
|
||||||
"description": "为 gdb 启用整齐打印",
|
"description": "为 gdb 启用整齐打印",
|
||||||
|
@ -4,8 +4,7 @@ project(atpg)
|
|||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
# 设置编译器优化选项
|
# 设置编译器优化选项
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Ofast -march=native -flto")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
|
|
||||||
|
|
||||||
# 设置源文件和头文件的路径
|
# 设置源文件和头文件的路径
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/src SOURCES)
|
aux_source_directory(${PROJECT_SOURCE_DIR}/src SOURCES)
|
||||||
|
5
crun
5
crun
@ -2,14 +2,13 @@
|
|||||||
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
cmake .
|
cmake . && make -j
|
||||||
make -j
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "compile failed."
|
echo "compile failed."
|
||||||
else
|
else
|
||||||
clear
|
clear
|
||||||
echo "========================"
|
echo "========================"
|
||||||
time ./atpg -i $1 --lut 8
|
time ./atpg -i $1 --lut=8 --seed=19260817
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -62,13 +62,13 @@ int LUTCircuit::check() {
|
|||||||
|
|
||||||
printf("unsat_lut: %d\n", unsatisfied_lut);
|
printf("unsat_lut: %d\n", unsatisfied_lut);
|
||||||
printf("score_value_unsatisfied_cost: %d\n", score_value_unsatisfied_cost);
|
printf("score_value_unsatisfied_cost: %d\n", score_value_unsatisfied_cost);
|
||||||
printf("score_fault_detected_weight: %d\n", score_fault_detected_weight);
|
// printf("score_fault_detected_weight: %d\n", score_fault_detected_weight);
|
||||||
printf("score_fault_propagated_weight: %d\n", score_fault_propagated_weight);
|
// printf("score_fault_propagated_weight: %d\n", score_fault_propagated_weight);
|
||||||
printf("score_fault_update_cost: %d\n", score_fault_update_cost);
|
// printf("score_fault_update_cost: %d\n", score_fault_update_cost);
|
||||||
|
|
||||||
int score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost;
|
int score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost;
|
||||||
|
|
||||||
printf("score: %d\n", score);
|
// printf("score: %d\n", score);
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
@ -4,7 +4,6 @@
|
|||||||
#include "circuit.h"
|
#include "circuit.h"
|
||||||
#include "paras.h"
|
#include "paras.h"
|
||||||
|
|
||||||
|
|
||||||
void LUTCircuit::print() {
|
void LUTCircuit::print() {
|
||||||
|
|
||||||
std::set<Gate*> st;
|
std::set<Gate*> st;
|
||||||
@ -38,10 +37,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();
|
||||||
|
C->C = this;
|
||||||
|
|
||||||
std::unordered_map<Gate*, LUT*> gate2LUT;
|
std::unordered_map<Gate*, LUT*> gate2LUT;
|
||||||
|
|
||||||
@ -89,19 +88,14 @@ LUTCircuit* Circuit::build_lut_circuit() {
|
|||||||
|
|
||||||
lut->name = lut->gate->name.c_str();
|
lut->name = lut->gate->name.c_str();
|
||||||
|
|
||||||
|
|
||||||
std::sort(lut->inner_gates.begin(), lut->inner_gates.end(), [](Gate* a, Gate* b) {
|
std::sort(lut->inner_gates.begin(), lut->inner_gates.end(), [](Gate* a, Gate* b) {
|
||||||
return a->id < b->id;
|
return a->id < b->id;
|
||||||
});
|
});
|
||||||
|
|
||||||
for(Gate* in : lut->__gate_fanins) {
|
for(Gate* in : lut->__gate_fanins) {
|
||||||
|
|
||||||
// if(gate2LUT.count(in) == 0) {
|
|
||||||
// printf("error: %s %s\n", in->name.c_str(), lut->name);
|
|
||||||
// // exit()
|
|
||||||
// }
|
|
||||||
assert(gate2LUT.count(in) > 0);
|
assert(gate2LUT.count(in) > 0);
|
||||||
|
|
||||||
|
|
||||||
lut->fanins.push_back(gate2LUT[in]);
|
lut->fanins.push_back(gate2LUT[in]);
|
||||||
gate2LUT[in]->fanouts.push_back(lut);
|
gate2LUT[in]->fanouts.push_back(lut);
|
||||||
}
|
}
|
||||||
@ -128,6 +122,23 @@ LUTCircuit* Circuit::build_lut_circuit() {
|
|||||||
return a->gate->rtopo < b->gate->rtopo;
|
return a->gate->rtopo < b->gate->rtopo;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for(LUT* lut : C->luts) {
|
||||||
|
for(Gate* g : lut->inner_gates) {
|
||||||
|
g->parent_lut = lut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,17 +171,27 @@ void Circuit::init_topo_index() {
|
|||||||
topo = 1;
|
topo = 1;
|
||||||
std::unordered_map<Gate*, int> outs;
|
std::unordered_map<Gate*, int> outs;
|
||||||
|
|
||||||
for(auto out : POs) {
|
for(Gate* g : gates) {
|
||||||
out->rtopo = topo++;
|
if(g->fanouts.size() == 0) {
|
||||||
q.push(out);
|
g->rtopo = topo++;
|
||||||
|
q.push(g);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(Gate* gate : gates) {
|
||||||
|
outs[gate] = gate->fanouts.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_set<Gate*> ok;
|
||||||
|
|
||||||
while(!q.empty()) {
|
while(!q.empty()) {
|
||||||
Gate* g = q.front(); q.pop();
|
Gate* g = q.front(); q.pop();
|
||||||
rtopo_gates.push_back(g);
|
rtopo_gates.push_back(g);
|
||||||
|
ok.insert(g);
|
||||||
for(Gate* in : g->fanins) {
|
for(Gate* in : g->fanins) {
|
||||||
outs[in]++;
|
outs[in]--;
|
||||||
if(outs[in] == in->fanouts.size()) {
|
|
||||||
|
if(outs[in] == 0) {
|
||||||
in->rtopo = topo++;
|
in->rtopo = topo++;
|
||||||
q.push(in);
|
q.push(in);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
using ll = long long;
|
using ll = long long;
|
||||||
|
|
||||||
class Simulator;
|
class Simulator;
|
||||||
|
class Circuit;
|
||||||
|
|
||||||
class LUTCircuit {
|
class LUTCircuit {
|
||||||
public:
|
public:
|
||||||
@ -14,25 +15,24 @@ std::vector<LUT*> POs;
|
|||||||
std::vector<LUT*> luts;
|
std::vector<LUT*> luts;
|
||||||
std::vector<LUT*> rtopo_luts;
|
std::vector<LUT*> rtopo_luts;
|
||||||
|
|
||||||
int step;
|
|
||||||
|
|
||||||
void print();
|
void print();
|
||||||
|
|
||||||
std::vector<LUT*> good_luts;
|
|
||||||
|
|
||||||
// local search
|
// local search
|
||||||
|
void ls_update(std::vector<LUT*> &unsat);
|
||||||
void ls_update();
|
|
||||||
LUT* ls_pick();
|
LUT* ls_pick();
|
||||||
void ls_flip(LUT *lut);
|
void ls_flip(LUT *lut);
|
||||||
void ls_main();
|
void ls_main();
|
||||||
|
void ls_init();
|
||||||
|
void ls_random_sol(int **fault_detected);
|
||||||
|
void ls_gen_sol();
|
||||||
|
|
||||||
// checker
|
// checker
|
||||||
|
|
||||||
int check();
|
int check();
|
||||||
|
|
||||||
|
|
||||||
Simulator *simulator;
|
Simulator *simulator;
|
||||||
|
Circuit *C;
|
||||||
|
|
||||||
|
int step;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,6 +6,11 @@ int Gate::cal_propagate_len(bool x) {
|
|||||||
|
|
||||||
int fpl[2];
|
int fpl[2];
|
||||||
fpl[0] = fpl[1] = 0;
|
fpl[0] = fpl[1] = 0;
|
||||||
|
if(isPO) {
|
||||||
|
fpl[!value] = 0;
|
||||||
|
fpl[value] = 0;
|
||||||
|
return fpl[x];
|
||||||
|
}
|
||||||
|
|
||||||
for(Gate* out : fanouts) {
|
for(Gate* out : fanouts) {
|
||||||
if(!out->is_detected(this)) continue;
|
if(!out->is_detected(this)) continue;
|
||||||
@ -17,7 +22,7 @@ int Gate::cal_propagate_len(bool x) {
|
|||||||
|
|
||||||
bool Gate::is_detected(Gate* one_of_input) {
|
bool Gate::is_detected(Gate* one_of_input) {
|
||||||
one_of_input->value = !one_of_input->value;
|
one_of_input->value = !one_of_input->value;
|
||||||
bool detect = cal_value() != value;
|
bool detect = (cal_value() != value);
|
||||||
one_of_input->value = !one_of_input->value;
|
one_of_input->value = !one_of_input->value;
|
||||||
return (cal_value() == value) && detect;
|
return (cal_value() == value) && detect;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@ -9,6 +8,8 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
class LUT;
|
||||||
|
|
||||||
class Gate {
|
class Gate {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -42,6 +43,9 @@ public:
|
|||||||
|
|
||||||
int cal_propagate_len(bool x);
|
int cal_propagate_len(bool x);
|
||||||
|
|
||||||
|
LUT* parent_lut;
|
||||||
|
int id_in_lut;
|
||||||
|
|
||||||
// ( 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 }
|
||||||
|
324
src/ls.cpp
324
src/ls.cpp
@ -1,4 +1,6 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "circuit.h"
|
#include "circuit.h"
|
||||||
#include "paras.h"
|
#include "paras.h"
|
||||||
@ -8,78 +10,47 @@ LUT* LUTCircuit::ls_pick() {
|
|||||||
|
|
||||||
LUT* pick = nullptr;
|
LUT* pick = nullptr;
|
||||||
|
|
||||||
// for(LUT* lut : luts) {
|
// 采样
|
||||||
// if(!lut->vsat) return lut;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// assert(false);
|
if(pick != nullptr) {
|
||||||
|
|
||||||
if(rand() % 10000 <= OPT(brk_sp) * 10000) {
|
|
||||||
printf("BREAK!!!!!\n");
|
|
||||||
pick = luts[rand() % luts.size()];
|
|
||||||
return pick;
|
return pick;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(good_luts.size() > 0) {
|
std::vector<LUT*> unsat;
|
||||||
pick = good_luts[rand() % good_luts.size()];
|
|
||||||
if(pick->score <= 0 || pick->tabu > step) {
|
|
||||||
pick = nullptr;
|
|
||||||
for(int i=0; i<good_luts.size(); i++) {
|
|
||||||
if(good_luts[i]->score <= 0 || good_luts[i]->tabu > step) {
|
|
||||||
good_luts[i]->is_good_var = 0;
|
|
||||||
good_luts[i] = good_luts.back();
|
|
||||||
good_luts.pop_back();
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(good_luts.size() > 0) {
|
// 动态加权
|
||||||
pick = good_luts[rand() % good_luts.size()];
|
ls_update(unsat);
|
||||||
assert(pick->score > 0 && pick->tabu <= step);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pick == nullptr) {
|
if(unsat.size() == 0) return nullptr;
|
||||||
printf("UPDATE!!!!!\n");
|
|
||||||
ls_update();
|
|
||||||
|
|
||||||
std::vector<LUT*> t;
|
return unsat[rand() % unsat.size()];
|
||||||
|
|
||||||
for(LUT* lut : luts) {
|
|
||||||
if(!lut->vsat) {
|
|
||||||
t.push_back(lut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pick = t[rand() % t.size()];
|
|
||||||
|
|
||||||
// pick = luts[rand() % luts.size()];
|
|
||||||
|
|
||||||
assert(pick != nullptr);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
printf("GOOD_VAR!!!!!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return pick;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LUTCircuit::ls_flip(LUT *lut) {
|
void LUTCircuit::ls_flip(LUT *lut) {
|
||||||
|
|
||||||
|
lut->CC = 0;
|
||||||
lut->uptag = 0;
|
lut->uptag = 0;
|
||||||
lut->value = !lut->value;
|
lut->flip_value();
|
||||||
if(!lut->isPI) lut->vsat = !lut->vsat;
|
if(!lut->isPI) lut->vsat = !lut->vsat;
|
||||||
|
|
||||||
lut->tabu = lut->vunat_cost + step;
|
|
||||||
|
|
||||||
for(LUT* out : lut->fanouts) {
|
for(LUT* out : lut->fanouts) {
|
||||||
|
out->CC = 1;
|
||||||
out->vsat = (out->cal_value() == out->value);
|
out->vsat = (out->cal_value() == out->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
lut->cal_fault_info(lut->fd, lut->fpl);
|
lut->cal_fault_info(lut->fd, lut->fpl);
|
||||||
|
|
||||||
for(LUT* r : lut->reigon) {
|
for(LUT* r : lut->reigon) {
|
||||||
|
r->CC = 1;
|
||||||
int t_fd[2], t_fpl[2];
|
int t_fd[2], t_fpl[2];
|
||||||
r->cal_fault_info(t_fd, t_fpl);
|
r->cal_fault_info(t_fd, t_fpl);
|
||||||
|
|
||||||
@ -87,41 +58,158 @@ void LUTCircuit::ls_flip(LUT *lut) {
|
|||||||
r->uptag = 1;
|
r->uptag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lut->cal_score();
|
|
||||||
for(LUT* r : lut->reigon) {
|
|
||||||
r->cal_score();
|
|
||||||
}
|
|
||||||
for(LUT* r : lut->fanouts) {
|
|
||||||
r->cal_score();
|
|
||||||
}
|
|
||||||
for(LUT* r : lut->update_reigon) {
|
|
||||||
r->cal_update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LUTCircuit::ls_update() {
|
void LUTCircuit::ls_update(std::vector<LUT*> &unsat) {
|
||||||
|
|
||||||
std::unordered_set<LUT*> need_up;
|
// if(rand() % 10000 <= OPT(sp)) {
|
||||||
|
|
||||||
for(LUT* lut : luts) {
|
// } else {
|
||||||
if(!lut->vsat) {
|
|
||||||
lut->vunat_cost += OPT(vsat_inc);
|
|
||||||
need_up.insert(lut);
|
for(LUT* lut : luts) {
|
||||||
need_up.insert(lut->fanins.begin(), lut->fanins.end());
|
if(!lut->vsat) {
|
||||||
|
if(lut->vunat_cost += OPT(vsat_inc) > OPT(vsat_max)) {
|
||||||
|
lut->vunat_cost = OPT(vsat_max);
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
|
|
||||||
for(LUT* lut : need_up) {
|
|
||||||
lut->cal_score();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LUTCircuit::ls_main() {
|
void LUTCircuit::ls_main() {
|
||||||
|
|
||||||
printf("====== local search start ======\n");
|
printf("====== local search start ======\n");
|
||||||
|
|
||||||
printf("initing lookup table ...\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());
|
||||||
|
int** 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");
|
||||||
|
|
||||||
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
while(num_undetected_fault != 0) {
|
||||||
|
|
||||||
|
ls_random_sol(fault_detected);
|
||||||
|
|
||||||
|
ls_gen_sol();
|
||||||
|
|
||||||
|
int res = simulator->verify(this);
|
||||||
|
assert(res == 1);
|
||||||
|
|
||||||
|
int num_fault = 0;
|
||||||
|
|
||||||
|
for(Gate* g : simulator->gates) {
|
||||||
|
if(g->fault_detected[0] && !fault_detected[g->id-1][0]) {
|
||||||
|
fault_detected[g->id-1][0] = 1;
|
||||||
|
num_detected_fault++;
|
||||||
|
num_undetected_fault--;
|
||||||
|
num_fault++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(g->fault_detected[1] && !fault_detected[g->id-1][1]) {
|
||||||
|
fault_detected[g->id-1][1] = 1;
|
||||||
|
num_detected_fault++;
|
||||||
|
num_undetected_fault--;
|
||||||
|
num_fault++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(num_fault > 0) {
|
||||||
|
num_pattern++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Cover: %.2f%% pattern: %d new_detected: %d undected: %d\n", (double)num_detected_fault / num_total_fault * 100, num_pattern, num_fault, num_undetected_fault);
|
||||||
|
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
|
||||||
|
for(int step=0; ; step++) {
|
||||||
|
// printf("step: %d\n", step);
|
||||||
|
// int t1 = check();
|
||||||
|
|
||||||
|
LUT* pick = ls_pick();
|
||||||
|
|
||||||
|
if(pick == nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pick->cal_score();
|
||||||
|
|
||||||
|
ls_flip(pick);
|
||||||
|
|
||||||
|
// int t2 = check();
|
||||||
|
// assert(t2 - t1 == pick->score);
|
||||||
|
|
||||||
|
// if(pick->isPI) {
|
||||||
|
// int score;
|
||||||
|
// simulator->simulate(PIs, score);
|
||||||
|
// printf("step: %d fd: %d\n", step, score);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LUTCircuit::ls_init() {
|
||||||
for(LUT* lut : luts) {
|
for(LUT* lut : luts) {
|
||||||
lut->init_lookup_table();
|
lut->init_lookup_table();
|
||||||
}
|
}
|
||||||
@ -169,10 +257,12 @@ void LUTCircuit::ls_main() {
|
|||||||
for(LUT* r : t_reigon) {
|
for(LUT* r : t_reigon) {
|
||||||
lut->update_reigon.push_back(r);
|
lut->update_reigon.push_back(r);
|
||||||
}
|
}
|
||||||
// printf("rg: %d %d\n", lut->reigon.size(), lut->update_reigon.size());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
printf("generating initial solution ...\n");
|
void LUTCircuit::ls_random_sol(int **fault_detected) {
|
||||||
|
|
||||||
|
step = 0;
|
||||||
|
|
||||||
for(LUT* lut : luts) {
|
for(LUT* lut : luts) {
|
||||||
lut->up_cost = 1;
|
lut->up_cost = 1;
|
||||||
@ -183,10 +273,14 @@ void LUTCircuit::ls_main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lut->is_good_var = 0;
|
lut->is_good_var = 0;
|
||||||
lut->tabu = 0;
|
lut->CC = 1;
|
||||||
for(Gate* g : lut->inner_gates) {
|
for(Gate* g : lut->inner_gates) {
|
||||||
g->fault_detected_weight[0] = g->fault_detected_weight[1] = 1;
|
|
||||||
g->fault_propagated_weight[0] = g->fault_propagated_weight[1] = 1;
|
g->fault_detected_weight[0] = !fault_detected[g->id-1][0];
|
||||||
|
g->fault_detected_weight[1] = !fault_detected[g->id-1][1];
|
||||||
|
|
||||||
|
g->fault_propagated_weight[0] = !fault_detected[g->id-1][0];
|
||||||
|
g->fault_propagated_weight[1] = !fault_detected[g->id-1][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,10 +290,16 @@ void LUTCircuit::ls_main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(LUT* lut : luts) {
|
for(LUT* lut : luts) {
|
||||||
lut->vsat = (lut->value == lut->cal_value());
|
lut->input_var = 0;
|
||||||
|
for(int i=0; i<lut->fanins.size(); i++) {
|
||||||
|
LUT* in = lut->fanins[i];
|
||||||
|
lut->input_var |= (in->value << i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("topo: %d %d\n", luts.size(), rtopo_luts.size());
|
for(LUT* lut : luts) {
|
||||||
|
lut->vsat = (lut->value == lut->cal_value());
|
||||||
|
}
|
||||||
|
|
||||||
for(LUT* lut : rtopo_luts) {
|
for(LUT* lut : rtopo_luts) {
|
||||||
lut->cal_fault_info(lut->fd, lut->fpl);
|
lut->cal_fault_info(lut->fd, lut->fpl);
|
||||||
@ -208,64 +308,4 @@ void LUTCircuit::ls_main() {
|
|||||||
for(LUT* lut : luts) {
|
for(LUT* lut : luts) {
|
||||||
lut->cal_score();
|
lut->cal_score();
|
||||||
}
|
}
|
||||||
|
|
||||||
step = 0;
|
|
||||||
|
|
||||||
print();
|
|
||||||
|
|
||||||
int seed = time(0);
|
|
||||||
srand(1689658115);
|
|
||||||
|
|
||||||
int T = 100000;
|
|
||||||
while(T--) {
|
|
||||||
|
|
||||||
if(T % 1000 == 0) {
|
|
||||||
printf("T: %d\n", T);
|
|
||||||
}
|
|
||||||
|
|
||||||
// int t1 = check();
|
|
||||||
|
|
||||||
// print();
|
|
||||||
|
|
||||||
LUT* pick = ls_pick();
|
|
||||||
// pick->cal_score();
|
|
||||||
|
|
||||||
printf(">>>> flip: %s\n", pick->name);
|
|
||||||
|
|
||||||
// int s = pick->score;
|
|
||||||
|
|
||||||
printf("##### score: %d seed: %d\n", pick->score, seed);
|
|
||||||
printf("vusat_cost: %d fdw: %d fplw: %d up: %d\n", pick->score_value_unsatisfied_cost, pick->score_fault_detected_weight, pick->score_fault_propagated_weight, pick->score_fault_update_cost);
|
|
||||||
|
|
||||||
int score;
|
|
||||||
simulator->simulate(PIs, score);
|
|
||||||
printf("score: %d\n", score);
|
|
||||||
|
|
||||||
ls_flip(pick);
|
|
||||||
|
|
||||||
// int t2 = check();
|
|
||||||
check();
|
|
||||||
|
|
||||||
int cnt = 0;
|
|
||||||
for(LUT* lut : luts) {
|
|
||||||
if(!lut->vsat) cnt++;
|
|
||||||
}
|
|
||||||
printf("unsat: %d\n", cnt);
|
|
||||||
|
|
||||||
// print();
|
|
||||||
|
|
||||||
// assert(s == (t2 - t1));
|
|
||||||
step++;
|
|
||||||
|
|
||||||
for(LUT *lut : luts) {
|
|
||||||
if(!lut->is_good_var && lut->score > 0 && lut->tabu <= step) {
|
|
||||||
lut->is_good_var = 1;
|
|
||||||
good_luts.push_back(lut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// print();
|
|
||||||
// exit(0);
|
|
||||||
|
|
||||||
}
|
}
|
149
src/lut.cpp
149
src/lut.cpp
@ -3,61 +3,53 @@
|
|||||||
#include "lut.h"
|
#include "lut.h"
|
||||||
#include "paras.h"
|
#include "paras.h"
|
||||||
|
|
||||||
void LUT::get_fault_info(Gate* gate, int *t_fd, int* t_fpl) {
|
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) {
|
void LUT::cal_fault_info(int *fd, int* fpl, int test) {
|
||||||
|
|
||||||
fd[0] = fd[1] = fpl[0] = fpl[1] = 0;
|
fd[0] = fd[1] = fpl[0] = fpl[1] = 0;
|
||||||
if(isPO) {
|
if(isPO) {
|
||||||
fd[0] = value;
|
fd[!value] = 1;
|
||||||
fd[1] = !value;
|
fd[value] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<fanouts.size(); i++) {
|
for(auto&[out, id] : fanouts_with_id) {
|
||||||
LUT* out = fanouts[i];
|
// if(!out->vsat) continue;
|
||||||
|
|
||||||
if(!out->vsat) continue;
|
FaultInfo &info = out->fault_table[id][out->input_var << 1 | out->value];
|
||||||
|
|
||||||
FaultInfo* info = nullptr;
|
|
||||||
|
|
||||||
int input = 0;
|
|
||||||
for(int j=0; j<out->fanins.size(); j++) {
|
|
||||||
if(out->fanins[j] == this) {
|
|
||||||
info = out->fault_table[j];
|
|
||||||
}
|
|
||||||
input |= (out->fanins[j]->value << j);
|
|
||||||
}
|
|
||||||
input <<= 1;
|
|
||||||
input |= out->value;
|
|
||||||
|
|
||||||
assert(info != nullptr);
|
|
||||||
|
|
||||||
int t_fd[2], t_fpl[2];
|
int t_fd[2], t_fpl[2];
|
||||||
|
|
||||||
t_fd[0] = info[input].fd[0] && out->fd[!value];
|
t_fd[0] = info.fd[0] && out->fd[!out->value];
|
||||||
t_fd[1] = info[input].fd[1] && out->fd[!value];
|
t_fd[1] = info.fd[1] && out->fd[!out->value];
|
||||||
|
|
||||||
t_fpl[0] = info[input].fpl[0] + info[input].fd[0] * out->fpl[!value];
|
t_fpl[0] = info.fpl[0] + info.fd[0] * out->fpl[!out->value];
|
||||||
t_fpl[1] = info[input].fpl[1] + info[input].fd[1] * out->fpl[!value];
|
t_fpl[1] = info.fpl[1] + info.fd[1] * out->fpl[!out->value];
|
||||||
|
|
||||||
fd[0] = std::max(fd[0], t_fd[0]);
|
fd[0] |= t_fd[0];
|
||||||
fd[1] = std::max(fd[1], t_fd[1]);
|
fd[1] |= t_fd[1];
|
||||||
|
|
||||||
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]);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int LUT::cal_value() {
|
int LUT::cal_value() {
|
||||||
if(isPI) return value;
|
if(isPI) return value;
|
||||||
int input = 0;
|
return value_table[input_var];
|
||||||
for(int i=0; i<fanins.size(); i++) {
|
|
||||||
input |= (fanins[i]->value << i);
|
|
||||||
}
|
|
||||||
return value_table[input];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LUT::LUT(Gate *gate, LUTCircuit *circuit):gate(gate), value(gate->value), name(gate->name.c_str()) {
|
LUT::LUT(Gate *gate, LUTCircuit *circuit):gate(gate), value(gate->value), name(gate->name.c_str()) {
|
||||||
@ -73,7 +65,6 @@ LUT::LUT(Gate *gate, LUTCircuit *circuit):gate(gate), value(gate->value), name(g
|
|||||||
|
|
||||||
for(Gate* g : gate->fanins) {
|
for(Gate* g : gate->fanins) {
|
||||||
fanins.insert(g);
|
fanins.insert(g);
|
||||||
// printf("init fanins: %s\n", g->name.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
@ -112,6 +103,7 @@ LUT::LUT(Gate *gate, LUTCircuit *circuit):gate(gate), value(gate->value), name(g
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LUT::init_lookup_table() {
|
void LUT::init_lookup_table() {
|
||||||
value_table = new int[1 << fanins.size()];
|
value_table = new int[1 << fanins.size()];
|
||||||
fault_table = new FaultInfo *[fanins.size() + inner_gates.size()];
|
fault_table = new FaultInfo *[fanins.size() + inner_gates.size()];
|
||||||
@ -119,20 +111,19 @@ void LUT::init_lookup_table() {
|
|||||||
fault_table[i] = new FaultInfo[1 << (fanins.size() + 1)];
|
fault_table[i] = new FaultInfo[1 << (fanins.size() + 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<Gate*, int> gate_to_index;
|
std::unordered_map<Gate*, int> gate2index;
|
||||||
|
|
||||||
for(int i=0; i<fanins.size(); i++) {
|
for(int i=0; i<fanins.size(); i++) {
|
||||||
gate_to_index[fanins[i]->gate] = i;
|
gate2index[fanins[i]->gate] = i;
|
||||||
}
|
}
|
||||||
for(int i=0; i<inner_gates.size(); i++) {
|
for(int i=0; i<inner_gates.size(); i++) {
|
||||||
gate_to_index[inner_gates[i]] = i + fanins.size();
|
gate2index[inner_gates[i]] = i + fanins.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < (1 << fanins.size()); i++) {
|
for (int i = 0; i < (1 << fanins.size()); i++) {
|
||||||
for (int j = 0; j < fanins.size(); j++) {
|
for (int j = 0; j < fanins.size(); j++) {
|
||||||
fanins[j]->gate->value = (i >> j) & 1;
|
fanins[j]->gate->value = (i >> j) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Gate *g : inner_gates) {
|
for (Gate *g : inner_gates) {
|
||||||
g->value = g->cal_value();
|
g->value = g->cal_value();
|
||||||
}
|
}
|
||||||
@ -141,61 +132,49 @@ void LUT::init_lookup_table() {
|
|||||||
|
|
||||||
value_table[i] = gate->value;
|
value_table[i] = gate->value;
|
||||||
|
|
||||||
gate->value = 0;
|
for(gate->value=0; gate->value<=1; gate->value++) {
|
||||||
gate->fault_detected[0] = 0;
|
|
||||||
gate->fault_detected[1] = 1;
|
|
||||||
gate->fault_propagated_len[0] = 0;
|
|
||||||
gate->fault_propagated_len[1] = 0;
|
|
||||||
|
|
||||||
// continue;
|
for(auto&[g, index] : gate2index) {
|
||||||
|
g->fault_detected[0] = g->fault_detected[1] = 0;
|
||||||
std::queue<Gate *> q;
|
g->fault_propagated_len[0] = g->fault_propagated_len[1] = 0;
|
||||||
q.push(gate);
|
|
||||||
|
|
||||||
while (!q.empty()) {
|
|
||||||
Gate *g = q.front();
|
|
||||||
q.pop();
|
|
||||||
|
|
||||||
fault_table[gate_to_index[g]][(i<<1)|gate->value].fd[0] = g->fault_detected[0];
|
|
||||||
fault_table[gate_to_index[g]][(i<<1)|gate->value].fd[1] = g->fault_detected[1];
|
|
||||||
|
|
||||||
fault_table[gate_to_index[g]][(i<<1)|gate->value].fpl[0] = g->fault_propagated_len[0];
|
|
||||||
fault_table[gate_to_index[g]][(i<<1)|gate->value].fpl[1] = g->fault_propagated_len[1];
|
|
||||||
|
|
||||||
for (Gate *fanin : g->fanins) {
|
|
||||||
fanin->fault_detected[0] = fanin->cal_fault_detected(0);
|
|
||||||
fanin->fault_detected[1] = fanin->cal_fault_detected(1);
|
|
||||||
fanin->fault_propagated_len[0] = fanin->cal_propagate_len(0);
|
|
||||||
fanin->fault_propagated_len[1] = fanin->cal_propagate_len(1);
|
|
||||||
|
|
||||||
if(gate_to_index.count(fanin)) q.push(fanin);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gate->value = 1;
|
gate->fault_detected[!gate->value] = 1;
|
||||||
gate->fault_detected[0] = 1;
|
gate->fault_detected[gate->value] = 0;
|
||||||
gate->fault_detected[1] = 0;
|
gate->fault_propagated_len[0] = 0;
|
||||||
gate->fault_propagated_len[0] = 0;
|
gate->fault_propagated_len[1] = 0;
|
||||||
gate->fault_propagated_len[1] = 0;
|
|
||||||
|
|
||||||
q.push(gate);
|
std::queue<Gate*> q;
|
||||||
|
q.push(gate);
|
||||||
|
|
||||||
while (!q.empty()) {
|
while(!q.empty()) {
|
||||||
Gate *g = q.front();
|
Gate *now = q.front(); q.pop();
|
||||||
q.pop();
|
|
||||||
|
|
||||||
fault_table[gate_to_index[g]][(i<<1)|gate->value].fd[0] = g->fault_detected[0];
|
FaultInfo *info = &fault_table[gate2index[now]][(i<<1)|gate->value];
|
||||||
fault_table[gate_to_index[g]][(i<<1)|gate->value].fd[1] = g->fault_detected[1];
|
info->fd[0] = now->fault_detected[0];
|
||||||
fault_table[gate_to_index[g]][(i<<1)|gate->value].fpl[0] = g->fault_propagated_len[0];
|
info->fd[1] = now->fault_detected[1];
|
||||||
fault_table[gate_to_index[g]][(i<<1)|gate->value].fpl[1] = g->fault_propagated_len[1];
|
info->fpl[0] = now->fault_propagated_len[0];
|
||||||
|
info->fpl[1] = now->fault_propagated_len[1];
|
||||||
|
info->value = now->value;
|
||||||
|
|
||||||
for (Gate *fanin : g->fanins) {
|
// if(now->name == "new_n22_") {
|
||||||
fanin->fault_detected[0] = fanin->cal_fault_detected(0);
|
// printf("Gate: %s value: %d inputs: [ ", now->name.c_str(), now->value);
|
||||||
fanin->fault_detected[1] = fanin->cal_fault_detected(1);
|
// for(Gate *in : now->fanins) {
|
||||||
fanin->fault_propagated_len[0] = fanin->cal_propagate_len(0);
|
// printf("%s ", in->name.c_str());
|
||||||
fanin->fault_propagated_len[1] = fanin->cal_propagate_len(1);
|
// }
|
||||||
|
// printf("]\n");
|
||||||
|
// }
|
||||||
|
|
||||||
if(gate_to_index.count(fanin)) q.push(fanin);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
src/lut.h
21
src/lut.h
@ -14,15 +14,16 @@ public:
|
|||||||
|
|
||||||
bool isPI, isPO;
|
bool isPI, isPO;
|
||||||
|
|
||||||
|
uint32_t input_var;
|
||||||
|
|
||||||
std::vector<LUT *> fanins;
|
std::vector<LUT *> fanins;
|
||||||
|
|
||||||
std::vector<LUT *> fanouts;
|
std::vector<LUT *> fanouts;
|
||||||
|
std::vector<std::pair<LUT*, int>> fanouts_with_id;
|
||||||
|
|
||||||
std::vector<LUT *> reigon;
|
std::vector<LUT *> reigon;
|
||||||
std::vector<LUT *> update_reigon;
|
std::vector<LUT *> update_reigon;
|
||||||
|
|
||||||
std::vector<LUT *> add_update_to_this;
|
|
||||||
|
|
||||||
std::vector<Gate *> inner_gates;
|
std::vector<Gate *> inner_gates;
|
||||||
|
|
||||||
std::vector<Gate *> __gate_fanins;
|
std::vector<Gate *> __gate_fanins;
|
||||||
@ -30,6 +31,8 @@ public:
|
|||||||
std::unordered_map<Gate *, int> input_id;
|
std::unordered_map<Gate *, int> input_id;
|
||||||
|
|
||||||
int &value;
|
int &value;
|
||||||
|
void flip_value();
|
||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
int *value_table;
|
int *value_table;
|
||||||
@ -37,25 +40,25 @@ public:
|
|||||||
struct FaultInfo {
|
struct FaultInfo {
|
||||||
int fd[2];
|
int fd[2];
|
||||||
int fpl[2];
|
int fpl[2];
|
||||||
|
int value;
|
||||||
} **fault_table;
|
} **fault_table;
|
||||||
|
|
||||||
std::vector<FaultInfo *> fault_info;
|
std::vector<FaultInfo *> fault_info;
|
||||||
|
|
||||||
std::unordered_set<LUT *> update_luts;
|
|
||||||
|
|
||||||
void init_lookup_table();
|
void init_lookup_table();
|
||||||
|
|
||||||
// local search
|
// local search
|
||||||
|
bool vsat;
|
||||||
bool vsat, vunat_cost;
|
int vunat_cost;
|
||||||
bool uptag, up_cost;
|
bool uptag;
|
||||||
|
int up_cost;
|
||||||
int fd[2];
|
int fd[2];
|
||||||
int fpl[2];
|
int fpl[2];
|
||||||
int is_good_var;
|
int is_good_var;
|
||||||
int tabu;
|
int CC;
|
||||||
|
|
||||||
int cal_value();
|
int cal_value();
|
||||||
void cal_fault_info(int *t_fd, int *t_fpl);
|
void cal_fault_info(int *t_fd, int *t_fpl, int test = 0);
|
||||||
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
|
||||||
|
@ -7,7 +7,7 @@ int main(int argc, char *argv[]) {
|
|||||||
// 初始化命令行参数
|
// 初始化命令行参数
|
||||||
INIT_ARGS
|
INIT_ARGS
|
||||||
|
|
||||||
srand(19260817);
|
srand(OPT(seed));
|
||||||
|
|
||||||
Circuit *circuit = new Circuit();
|
Circuit *circuit = new Circuit();
|
||||||
Simulator* simulator = new Simulator();
|
Simulator* simulator = new Simulator();
|
||||||
@ -17,6 +17,7 @@ int main(int argc, char *argv[]) {
|
|||||||
simulator->parse_from_file(OPT(instance).c_str());
|
simulator->parse_from_file(OPT(instance).c_str());
|
||||||
circuit->init_topo_index();
|
circuit->init_topo_index();
|
||||||
simulator->init_topo_index();
|
simulator->init_topo_index();
|
||||||
|
// circuit->
|
||||||
|
|
||||||
printf("building lut circuit ...\n");
|
printf("building lut circuit ...\n");
|
||||||
LUTCircuit *C = circuit->build_lut_circuit();
|
LUTCircuit *C = circuit->build_lut_circuit();
|
||||||
@ -29,6 +30,8 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("LUT:\t%ld\n", C->luts.size());
|
printf("LUT:\t%ld\n", C->luts.size());
|
||||||
// printf("================================ \n");
|
// printf("================================ \n");
|
||||||
|
|
||||||
|
|
||||||
|
C->print();
|
||||||
C->ls_main();
|
C->ls_main();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
16
src/paras.h
16
src/paras.h
@ -7,11 +7,17 @@
|
|||||||
|
|
||||||
// name, type, short-name,must-need, default ,low, high, comments
|
// name, type, short-name,must-need, default ,low, high, comments
|
||||||
#define PARAS \
|
#define PARAS \
|
||||||
PARA( lut , int , '\0' , false , 8 , 0 , 16 , "max input numbers of LUT") \
|
PARA( seed , int , '\0' , false , 17 , 0 , 100000000 , "max input numbers of LUT") \
|
||||||
PARA( sp , double , '\0' , false , 0.01 , 0 , 1 , "max input numbers of LUT") \
|
PARA( lut , int , '\0' , false , 8 , 0 , 16 , "max input numbers of LUT") \
|
||||||
PARA( vsat_inc , int , '\0' , false , 20 , 0 , 16 , "max input numbers of LUT") \
|
PARA( sp , double , '\0' , false , 0.01 , 0 , 1 , "max input numbers of LUT") \
|
||||||
PARA( brk_sp , double , '\0' , false , 0.05 , 0 , 1 , "max input numbers of LUT")
|
PARA( brk_sp , double , '\0' , false , 0.05 , 0 , 1 , "max input numbers of LUT") \
|
||||||
|
PARA( t , int , '\0' , false , 50 , 0 , 1000 , "max input numbers of LUT") \
|
||||||
|
PARA( vsat_inc , int , '\0' , false , 2 , 0 , 100000 , "max input numbers of LUT") \
|
||||||
|
PARA( vsat_max , int , '\0' , false , 10000 , 0 , 100000 , "max input numbers of LUT") \
|
||||||
|
PARA( fw_inc , int , '\0' , false , 1 , 0 , 1000 , "max input numbers of LUT") \
|
||||||
|
PARA( fw_max , int , '\0' , false , 500 , 0 , 1000 , "max input numbers of LUT") \
|
||||||
|
PARA( up_inc , int , '\0' , false , 10 , 0 , 1000 , "max input numbers of LUT") \
|
||||||
|
PARA( up_max , int , '\0' , false , 10000 , 0 , 1000 , "max input numbers of LUT")
|
||||||
// name, short-name, must-need, default, comments
|
// name, short-name, must-need, default, comments
|
||||||
#define STR_PARAS \
|
#define STR_PARAS \
|
||||||
STR_PARA( instance , 'i' , true , "" , ".bench format instance")
|
STR_PARA( instance , 'i' , true , "" , ".bench format instance")
|
||||||
|
@ -1,79 +1,16 @@
|
|||||||
#include "lut.h"
|
#include "lut.h"
|
||||||
#include "circuit.h"
|
#include "circuit.h"
|
||||||
|
|
||||||
void LUT::cal_update() {
|
|
||||||
|
|
||||||
score_fault_update_cost = 0;
|
|
||||||
|
|
||||||
|
|
||||||
value = !value;
|
|
||||||
|
|
||||||
if(uptag) {
|
|
||||||
score_fault_update_cost -= up_cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
// value sat score
|
|
||||||
if(!isPI) {
|
|
||||||
vsat = !vsat;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(LUT* out : fanouts) {
|
|
||||||
out->vsat = ( out->cal_value() == out->value );
|
|
||||||
}
|
|
||||||
|
|
||||||
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];
|
|
||||||
|
|
||||||
// fault detected score
|
|
||||||
cal_fault_info(fd, fpl);
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value = !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;
|
|
||||||
|
|
||||||
if(!is_good_var && score > 0 && tabu <= C->step) {
|
|
||||||
is_good_var = 1;
|
|
||||||
C->good_luts.push_back(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LUT::cal_score() {
|
void LUT::cal_score() {
|
||||||
|
|
||||||
update_luts.clear();
|
|
||||||
|
|
||||||
score = 0;
|
score = 0;
|
||||||
score_value_unsatisfied_cost = 0;
|
score_value_unsatisfied_cost = 0;
|
||||||
score_fault_detected_weight = 0;
|
score_fault_detected_weight = 0;
|
||||||
score_fault_propagated_weight = 0;
|
score_fault_propagated_weight = 0;
|
||||||
score_fault_update_cost = 0;
|
score_fault_update_cost = 0;
|
||||||
|
|
||||||
// printf("old_fd: %d %d\n", old_fd[0], old_fd[1]);
|
// value = !value;
|
||||||
|
this->flip_value();
|
||||||
value = !value;
|
|
||||||
|
|
||||||
if(uptag) {
|
if(uptag) {
|
||||||
score_fault_update_cost -= up_cost;
|
score_fault_update_cost -= up_cost;
|
||||||
@ -110,17 +47,9 @@ void LUT::cal_score() {
|
|||||||
|
|
||||||
// printf("fd: %d %d %d %d\n", fd[0], fd[1], old_fd[0], old_fd[1]);
|
// printf("fd: %d %d %d %d\n", fd[0], fd[1], old_fd[0], old_fd[1]);
|
||||||
|
|
||||||
for(LUT* out : fanouts) {
|
for(auto&[out, id] : fanouts_with_id) {
|
||||||
int in1 = 0, in2 = 0;
|
uint32_t in1 = out->input_var, in2 = out->input_var;
|
||||||
for(int i=0; i<out->fanins.size(); i++) {
|
in1 ^= (1 << id);
|
||||||
if(out->fanins[i] == this) {
|
|
||||||
in1 |= (!value << i);
|
|
||||||
in2 |= (value << i);
|
|
||||||
} else {
|
|
||||||
in1 |= (out->fanins[i]->value << i);
|
|
||||||
in2 |= (out->fanins[i]->value << i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
in1 = (in1 << 1) | out->value;
|
in1 = (in1 << 1) | out->value;
|
||||||
in2 = (in2 << 1) | out->value;
|
in2 = (in2 << 1) | out->value;
|
||||||
@ -151,11 +80,7 @@ void LUT::cal_score() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int in1 = 0, in2 = 0;
|
int in1 = this->input_var, in2 = this->input_var;
|
||||||
for(int i=0; i<fanins.size(); i++) {
|
|
||||||
in1 |= (fanins[i]->value << i);
|
|
||||||
}
|
|
||||||
in2 = in1;
|
|
||||||
in1 = (in1 << 1) | !value;
|
in1 = (in1 << 1) | !value;
|
||||||
in2 = (in2 << 1) | value;
|
in2 = (in2 << 1) | value;
|
||||||
|
|
||||||
@ -189,15 +114,12 @@ void LUT::cal_score() {
|
|||||||
int t_fd[2], t_fpl[2];
|
int t_fd[2], t_fpl[2];
|
||||||
r->cal_fault_info(t_fd, t_fpl);
|
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(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) {
|
if(!r->uptag) {
|
||||||
score_fault_update_cost += r->up_cost;
|
score_fault_update_cost += r->up_cost;
|
||||||
update_luts.insert(r);
|
|
||||||
r->add_update_to_this.push_back(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value = !value;
|
this->flip_value();
|
||||||
if(!isPI) vsat = !vsat;
|
if(!isPI) vsat = !vsat;
|
||||||
|
|
||||||
fd[0] = old_fd[0];
|
fd[0] = old_fd[0];
|
||||||
@ -210,9 +132,4 @@ void LUT::cal_score() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost;
|
score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost;
|
||||||
|
|
||||||
if(!is_good_var && score > 0 && tabu <= C->step) {
|
|
||||||
is_good_var = 1;
|
|
||||||
C->good_luts.push_back(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,5 +1,82 @@
|
|||||||
#include "simulator.h"
|
#include "simulator.h"
|
||||||
|
|
||||||
|
int Simulator::verify(LUTCircuit *lut_circuit) {
|
||||||
|
|
||||||
|
// lut_circuit->check();
|
||||||
|
|
||||||
|
// for(LUT* lut : lut_circuit->PIs) {
|
||||||
|
// printf("PI: %s = %d\n", lut->name, lut->value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
int score;
|
||||||
|
simulate(lut_circuit->PIs, score);
|
||||||
|
|
||||||
|
for(LUT* lut : lut_circuit->luts) {
|
||||||
|
assert(lut->value == lut->cal_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(LUT* lut : lut_circuit->rtopo_luts) {
|
||||||
|
lut->cal_fault_info(lut->fd, lut->fpl, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// lut_circuit->print();
|
||||||
|
|
||||||
|
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) {
|
void Simulator::simulate(std::vector<LUT*> &inputs, int &score) {
|
||||||
|
|
||||||
assert(inputs.size() == this->PIs.size());
|
assert(inputs.size() == this->PIs.size());
|
||||||
@ -9,12 +86,14 @@ void Simulator::simulate(std::vector<LUT*> &inputs, int &score) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(auto gate : gates) {
|
for(auto gate : gates) {
|
||||||
gate->cal_value();
|
gate->value = gate->cal_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto gate : rtopo_gates) {
|
for(auto gate : rtopo_gates) {
|
||||||
gate->fault_detected[0] = gate->cal_fault_detected(0);
|
gate->fault_detected[0] = gate->cal_fault_detected(0);
|
||||||
gate->fault_detected[1] = gate->cal_fault_detected(1);
|
gate->fault_detected[1] = gate->cal_fault_detected(1);
|
||||||
|
gate->fault_propagated_len[0] = gate->cal_propagate_len(0);
|
||||||
|
gate->fault_propagated_len[1] = gate->cal_propagate_len(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
score = 0;
|
score = 0;
|
||||||
|
@ -5,4 +5,5 @@
|
|||||||
class Simulator : public Circuit {
|
class Simulator : public Circuit {
|
||||||
public:
|
public:
|
||||||
void simulate(std::vector<LUT*> &inputs, int &score);
|
void simulate(std::vector<LUT*> &inputs, int &score);
|
||||||
|
int verify(LUTCircuit *lut_circuit);
|
||||||
};
|
};
|
6
test.py
6
test.py
@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
while os.system("./crun benchmark/b12.bench") == 0:
|
for i in range(10000):
|
||||||
pass
|
res = os.system("./atpg -i ./benchmark/c432.bench --lut=8 --seed=%d" % i)
|
||||||
|
if res != 0:
|
||||||
|
break
|
||||||
|
Loading…
x
Reference in New Issue
Block a user