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",
|
||||
"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 启用整齐打印",
|
||||
|
@ -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)
|
||||
|
5
crun
5
crun
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 }
|
||||
|
330
src/ls.cpp
330
src/ls.cpp
@ -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);
|
||||
|
||||
}
|
149
src/lut.cpp
149
src/lut.cpp
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
src/lut.h
21
src/lut.h
@ -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
|
||||
|
@ -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;
|
||||
|
16
src/paras.h
16
src/paras.h
@ -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")
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -5,4 +5,5 @@
|
||||
class Simulator : public Circuit {
|
||||
public:
|
||||
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
|
||||
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user