v1.0: 实现了ATPG全流程

This commit is contained in:
YuhangQ 2023-08-09 07:47:50 +00:00
parent 535cc3bd81
commit ba70167a6b
20 changed files with 6073 additions and 375 deletions

BIN
.nfs00000000073d9db3000000b1 Executable file

Binary file not shown.

4
.vscode/launch.json vendored
View File

@ -9,12 +9,12 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/atpg",
"args": ["${workspaceFolder}/benchmark/c432.bench"],
"args": ["-i", "${workspaceFolder}/benchmark/c17.bench"],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",

View File

@ -4,8 +4,7 @@ project(atpg)
set(CMAKE_CXX_STANDARD 17)
#
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Ofast -march=native -flto")
#
aux_source_directory(${PROJECT_SOURCE_DIR}/src SOURCES)

BIN
atpg

Binary file not shown.

5
crun
View File

@ -2,14 +2,13 @@
clear
cmake .
make -j
cmake . && make -j
if [ $? -ne 0 ]; then
echo "compile failed."
else
clear
echo "========================"
time ./atpg -i $1 --lut 8
time ./atpg -i $1 --lut=8 --seed=19260817
fi

View File

@ -62,13 +62,13 @@ int LUTCircuit::check() {
printf("unsat_lut: %d\n", unsatisfied_lut);
printf("score_value_unsatisfied_cost: %d\n", score_value_unsatisfied_cost);
printf("score_fault_detected_weight: %d\n", score_fault_detected_weight);
printf("score_fault_propagated_weight: %d\n", score_fault_propagated_weight);
printf("score_fault_update_cost: %d\n", score_fault_update_cost);
// 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_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;
printf("score: %d\n", score);
// printf("score: %d\n", score);
return score;
}

View File

@ -4,7 +4,6 @@
#include "circuit.h"
#include "paras.h"
void LUTCircuit::print() {
std::set<Gate*> st;
@ -38,10 +37,10 @@ void LUTCircuit::print() {
printf("total gate: %d\n", total_gate);
}
LUTCircuit* Circuit::build_lut_circuit() {
LUTCircuit* C = new LUTCircuit();
C->C = this;
std::unordered_map<Gate*, LUT*> gate2LUT;
@ -89,19 +88,14 @@ LUTCircuit* Circuit::build_lut_circuit() {
lut->name = lut->gate->name.c_str();
std::sort(lut->inner_gates.begin(), lut->inner_gates.end(), [](Gate* a, Gate* b) {
return a->id < b->id;
});
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);
lut->fanins.push_back(gate2LUT[in]);
gate2LUT[in]->fanouts.push_back(lut);
}
@ -128,6 +122,23 @@ LUTCircuit* Circuit::build_lut_circuit() {
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;
}
@ -160,20 +171,30 @@ void Circuit::init_topo_index() {
topo = 1;
std::unordered_map<Gate*, int> outs;
for(auto out : POs) {
out->rtopo = topo++;
q.push(out);
for(Gate* g : gates) {
if(g->fanouts.size() == 0) {
g->rtopo = topo++;
q.push(g);
}
}
for(Gate* gate : gates) {
outs[gate] = gate->fanouts.size();
}
std::unordered_set<Gate*> ok;
while(!q.empty()) {
Gate* g = q.front(); q.pop();
rtopo_gates.push_back(g);
ok.insert(g);
for(Gate* in : g->fanins) {
outs[in]++;
if(outs[in] == in->fanouts.size()) {
outs[in]--;
if(outs[in] == 0) {
in->rtopo = topo++;
q.push(in);
}
}
}
}
}

View File

@ -6,6 +6,7 @@
using ll = long long;
class Simulator;
class Circuit;
class LUTCircuit {
public:
@ -14,25 +15,24 @@ std::vector<LUT*> POs;
std::vector<LUT*> luts;
std::vector<LUT*> rtopo_luts;
int step;
void print();
std::vector<LUT*> good_luts;
// local search
void ls_update();
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(int **fault_detected);
void ls_gen_sol();
// checker
int check();
Simulator *simulator;
Circuit *C;
int step;
};

View File

@ -3,9 +3,14 @@
#include "assert.h"
int Gate::cal_propagate_len(bool x) {
int fpl[2];
fpl[0] = fpl[1] = 0;
if(isPO) {
fpl[!value] = 0;
fpl[value] = 0;
return fpl[x];
}
for(Gate* out : fanouts) {
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) {
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;
return (cal_value() == value) && detect;
}

View File

@ -1,6 +1,5 @@
#pragma once
#include <string>
#include <vector>
#include <unordered_map>
@ -9,6 +8,8 @@
#include <algorithm>
#include <assert.h>
class LUT;
class Gate {
public:
@ -42,6 +43,9 @@ public:
int cal_propagate_len(bool x);
LUT* parent_lut;
int id_in_lut;
// ( partical ) score
// score(x) = for y in neibor(x) { ~V_x,V_y make - ~V_x,V_y break }

View File

@ -1,4 +1,6 @@
#include <set>
#include <chrono>
#include <iostream>
#include "circuit.h"
#include "paras.h"
@ -7,79 +9,48 @@
LUT* LUTCircuit::ls_pick() {
LUT* pick = nullptr;
// for(LUT* lut : luts) {
// if(!lut->vsat) return lut;
// }
// assert(false);
if(rand() % 10000 <= OPT(brk_sp) * 10000) {
printf("BREAK!!!!!\n");
pick = luts[rand() % luts.size()];
return pick;
}
if(good_luts.size() > 0) {
pick = good_luts[rand() % good_luts.size()];
if(pick->score <= 0 || pick->tabu > step) {
pick = nullptr;
for(int i=0; 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()];
assert(pick->score > 0 && pick->tabu <= step);
}
// 采样
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;
}
}
if(pick == nullptr) {
printf("UPDATE!!!!!\n");
ls_update();
std::vector<LUT*> t;
for(LUT* lut : luts) {
if(!lut->vsat) {
t.push_back(lut);
}
}
pick = t[rand() % t.size()];
// pick = luts[rand() % luts.size()];
assert(pick != nullptr);
} else {
printf("GOOD_VAR!!!!!\n");
if(pick != nullptr) {
return pick;
}
return pick;
std::vector<LUT*> unsat;
// 动态加权
ls_update(unsat);
if(unsat.size() == 0) return nullptr;
return unsat[rand() % unsat.size()];
}
void LUTCircuit::ls_flip(LUT *lut) {
lut->CC = 0;
lut->uptag = 0;
lut->value = !lut->value;
lut->flip_value();
if(!lut->isPI) lut->vsat = !lut->vsat;
lut->tabu = lut->vunat_cost + step;
for(LUT* out : lut->fanouts) {
out->CC = 1;
out->vsat = (out->cal_value() == out->value);
}
lut->cal_fault_info(lut->fd, lut->fpl);
for(LUT* r : lut->reigon) {
r->CC = 1;
int t_fd[2], t_fpl[2];
r->cal_fault_info(t_fd, t_fpl);
@ -87,41 +58,158 @@ void LUTCircuit::ls_flip(LUT *lut) {
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) {
if(!lut->vsat) {
lut->vunat_cost += OPT(vsat_inc);
need_up.insert(lut);
need_up.insert(lut->fanins.begin(), lut->fanins.end());
// } else {
for(LUT* lut : luts) {
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() {
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());
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) {
lut->init_lookup_table();
}
@ -169,10 +257,12 @@ void LUTCircuit::ls_main() {
for(LUT* r : t_reigon) {
lut->update_reigon.push_back(r);
}
// printf("rg: %d %d\n", lut->reigon.size(), lut->update_reigon.size());
}
}
printf("generating initial solution ...\n");
void LUTCircuit::ls_random_sol(int **fault_detected) {
step = 0;
for(LUT* lut : luts) {
lut->up_cost = 1;
@ -183,10 +273,14 @@ void LUTCircuit::ls_main() {
}
lut->is_good_var = 0;
lut->tabu = 0;
lut->CC = 1;
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) {
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) {
lut->cal_fault_info(lut->fd, lut->fpl);
@ -208,64 +308,4 @@ void LUTCircuit::ls_main() {
for(LUT* lut : luts) {
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);
}

View File

@ -3,61 +3,53 @@
#include "lut.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;
if(isPO) {
fd[0] = value;
fd[1] = !value;
fd[!value] = 1;
fd[value] = 0;
return;
}
for(int i=0; i<fanouts.size(); i++) {
LUT* out = fanouts[i];
for(auto&[out, id] : fanouts_with_id) {
// if(!out->vsat) continue;
if(!out->vsat) continue;
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);
FaultInfo &info = out->fault_table[id][out->input_var << 1 | out->value];
int t_fd[2], t_fpl[2];
t_fd[0] = info[input].fd[0] && out->fd[!value];
t_fd[1] = info[input].fd[1] && out->fd[!value];
t_fd[0] = info.fd[0] && out->fd[!out->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[1] = info[input].fpl[1] + info[input].fd[1] * out->fpl[!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] = std::max(fd[0], t_fd[0]);
fd[1] = std::max(fd[1], t_fd[1]);
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]);
// 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() {
if(isPI) return value;
int input = 0;
for(int i=0; i<fanins.size(); i++) {
input |= (fanins[i]->value << i);
}
return value_table[input];
return value_table[input_var];
}
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) {
fanins.insert(g);
// printf("init fanins: %s\n", g->name.c_str());
}
while(true) {
@ -112,6 +103,7 @@ LUT::LUT(Gate *gate, LUTCircuit *circuit):gate(gate), value(gate->value), name(g
}
}
void LUT::init_lookup_table() {
value_table = new int[1 << fanins.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)];
}
std::unordered_map<Gate*, int> gate_to_index;
std::unordered_map<Gate*, int> gate2index;
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++) {
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 j = 0; j < fanins.size(); j++) {
fanins[j]->gate->value = (i >> j) & 1;
}
for (Gate *g : inner_gates) {
g->value = g->cal_value();
}
@ -141,61 +132,49 @@ void LUT::init_lookup_table() {
value_table[i] = gate->value;
gate->value = 0;
gate->fault_detected[0] = 0;
gate->fault_detected[1] = 1;
gate->fault_propagated_len[0] = 0;
gate->fault_propagated_len[1] = 0;
for(gate->value=0; gate->value<=1; gate->value++) {
// continue;
std::queue<Gate *> q;
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);
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->value = 1;
gate->fault_detected[0] = 1;
gate->fault_detected[1] = 0;
gate->fault_propagated_len[0] = 0;
gate->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;
q.push(gate);
std::queue<Gate*> q;
q.push(gate);
while (!q.empty()) {
Gate *g = q.front();
q.pop();
while(!q.empty()) {
Gate *now = 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];
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;
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(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");
// }
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);
}
}
}
}

View File

@ -14,15 +14,16 @@ public:
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<LUT *> add_update_to_this;
std::vector<Gate *> inner_gates;
std::vector<Gate *> __gate_fanins;
@ -30,6 +31,8 @@ public:
std::unordered_map<Gate *, int> input_id;
int &value;
void flip_value();
const char *name;
int *value_table;
@ -37,25 +40,25 @@ public:
struct FaultInfo {
int fd[2];
int fpl[2];
int value;
} **fault_table;
std::vector<FaultInfo *> fault_info;
std::unordered_set<LUT *> update_luts;
void init_lookup_table();
// local search
bool vsat, vunat_cost;
bool uptag, up_cost;
bool vsat;
int vunat_cost;
bool uptag;
int up_cost;
int fd[2];
int fpl[2];
int is_good_var;
int tabu;
int CC;
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);
// score

View File

@ -7,7 +7,7 @@ int main(int argc, char *argv[]) {
// 初始化命令行参数
INIT_ARGS
srand(19260817);
srand(OPT(seed));
Circuit *circuit = new Circuit();
Simulator* simulator = new Simulator();
@ -17,6 +17,7 @@ int main(int argc, char *argv[]) {
simulator->parse_from_file(OPT(instance).c_str());
circuit->init_topo_index();
simulator->init_topo_index();
// circuit->
printf("building lut circuit ...\n");
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("================================ \n");
C->print();
C->ls_main();
return 0;

View File

@ -7,11 +7,17 @@
// name, type, short-name,must-need, default ,low, high, comments
#define PARAS \
PARA( lut , int , '\0' , false , 8 , 0 , 16 , "max input numbers of LUT") \
PARA( sp , double , '\0' , false , 0.01 , 0 , 1 , "max input numbers of LUT") \
PARA( vsat_inc , int , '\0' , false , 20 , 0 , 16 , "max input numbers of LUT") \
PARA( brk_sp , double , '\0' , false , 0.05 , 0 , 1 , "max input numbers of LUT")
PARA( seed , int , '\0' , false , 17 , 0 , 100000000 , "max input numbers of LUT") \
PARA( lut , int , '\0' , false , 8 , 0 , 16 , "max input numbers of LUT") \
PARA( sp , double , '\0' , false , 0.01 , 0 , 1 , "max input numbers of LUT") \
PARA( 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
#define STR_PARAS \
STR_PARA( instance , 'i' , true , "" , ".bench format instance")

View File

@ -1,69 +1,7 @@
#include "lut.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() {
update_luts.clear();
score = 0;
score_value_unsatisfied_cost = 0;
@ -71,9 +9,8 @@ void LUT::cal_score() {
score_fault_propagated_weight = 0;
score_fault_update_cost = 0;
// printf("old_fd: %d %d\n", old_fd[0], old_fd[1]);
value = !value;
// value = !value;
this->flip_value();
if(uptag) {
score_fault_update_cost -= up_cost;
@ -85,7 +22,7 @@ void LUT::cal_score() {
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) {
@ -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]);
for(LUT* out : fanouts) {
int in1 = 0, in2 = 0;
for(int i=0; i<out->fanins.size(); i++) {
if(out->fanins[i] == this) {
in1 |= (!value << i);
in2 |= (value << i);
} else {
in1 |= (out->fanins[i]->value << i);
in2 |= (out->fanins[i]->value << i);
}
}
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;
@ -151,11 +80,7 @@ void LUT::cal_score() {
}
}
int in1 = 0, in2 = 0;
for(int i=0; i<fanins.size(); i++) {
in1 |= (fanins[i]->value << i);
}
in2 = in1;
int in1 = this->input_var, in2 = this->input_var;
in1 = (in1 << 1) | !value;
in2 = (in2 << 1) | value;
@ -189,15 +114,12 @@ void LUT::cal_score() {
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;
update_luts.insert(r);
r->add_update_to_this.push_back(this);
}
}
value = !value;
this->flip_value();
if(!isPI) vsat = !vsat;
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;
if(!is_good_var && score > 0 && tabu <= C->step) {
is_good_var = 1;
C->good_luts.push_back(this);
}
}

View File

@ -1,5 +1,82 @@
#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) {
assert(inputs.size() == this->PIs.size());
@ -9,12 +86,14 @@ void Simulator::simulate(std::vector<LUT*> &inputs, int &score) {
}
for(auto gate : gates) {
gate->cal_value();
gate->value = gate->cal_value();
}
for(auto gate : rtopo_gates) {
gate->fault_detected[0] = gate->cal_fault_detected(0);
gate->fault_detected[1] = gate->cal_fault_detected(1);
gate->fault_propagated_len[0] = gate->cal_propagate_len(0);
gate->fault_propagated_len[1] = gate->cal_propagate_len(1);
}
score = 0;

View File

@ -5,4 +5,5 @@
class Simulator : public Circuit {
public:
void simulate(std::vector<LUT*> &inputs, int &score);
int verify(LUTCircuit *lut_circuit);
};

View File

@ -1,5 +1,7 @@
import os
while os.system("./crun benchmark/b12.bench") == 0:
pass
for i in range(10000):
res = os.system("./atpg -i ./benchmark/c432.bench --lut=8 --seed=%d" % i)
if res != 0:
break

5640
test.txt Normal file

File diff suppressed because it is too large Load Diff