带sim的版本
This commit is contained in:
parent
4aa1c086b7
commit
535cc3bd81
20
CMakeLists.txt
Normal file
20
CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
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")
|
||||
|
||||
# 设置源文件和头文件的路径
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/src SOURCES)
|
||||
set(INCLUDES ${PROJECT_SOURCE_DIR}/src)
|
||||
|
||||
message(${SOURCES})
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
# 添加头文件
|
||||
include_directories(${INCLUDES})
|
2
crun
2
crun
@ -10,6 +10,6 @@ if [ $? -ne 0 ]; then
|
||||
else
|
||||
clear
|
||||
echo "========================"
|
||||
time ./atpg -i $1 --lut 4
|
||||
time ./atpg -i $1 --lut 8
|
||||
fi
|
||||
|
||||
|
@ -13,11 +13,16 @@ int LUTCircuit::check() {
|
||||
int score_fault_detected_weight = 0;
|
||||
int score_fault_propagated_weight = 0;
|
||||
int score_fault_update_cost = 0;
|
||||
int unsatisfied_lut = 0;
|
||||
|
||||
for(LUT* lut : luts) {
|
||||
assert(lut->vsat == (lut->value == lut->cal_value()));
|
||||
|
||||
if(!lut->vsat) score_value_unsatisfied_cost += lut->vunat_cost;
|
||||
if(!lut->vsat) {
|
||||
score_value_unsatisfied_cost += lut->vunat_cost;
|
||||
unsatisfied_lut++;
|
||||
// printf("vunsat: %s\n", lut->name);
|
||||
}
|
||||
|
||||
if(lut->uptag) {
|
||||
score_fault_update_cost += lut->up_cost;
|
||||
@ -46,20 +51,6 @@ int LUTCircuit::check() {
|
||||
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];
|
||||
|
||||
// if(lut->gate->name == "new_n546_") {
|
||||
// printf("new_n546_: %d %d %d %d\n", t_fd[0], t_fd[1], t_fpl[0], t_fpl[1]);
|
||||
// }
|
||||
|
||||
// if(t_fd[0] || t_fd[1]) {
|
||||
// printf("find: %s\n", g->name.c_str());
|
||||
// }
|
||||
|
||||
// printf("%10s - %10s fd %d %d fpl %d %d\n", lut->gate->name.c_str(), g->name.c_str(), t_fd[0], t_fd[1], t_fpl[0], t_fpl[1]);
|
||||
|
||||
// if(g->name == "new_n549_") {
|
||||
// printf("new_n549_: %d %d %d %d fa: %s\n", t_fd[0], t_fd[1], t_fpl[0], t_fpl[1], lut->gate->name.c_str());
|
||||
// }
|
||||
|
||||
score_fault_detected_weight += t_fd[0] * g->fault_detected_weight[0];
|
||||
score_fault_detected_weight += t_fd[1] * g->fault_detected_weight[1];
|
||||
@ -69,6 +60,7 @@ 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);
|
||||
|
@ -60,7 +60,7 @@ LUTCircuit* Circuit::build_lut_circuit() {
|
||||
Gate* gate = q.front();
|
||||
q.pop();
|
||||
|
||||
LUT* lut = new LUT(gate);
|
||||
LUT* lut = new LUT(gate, C);
|
||||
|
||||
gate2LUT[gate] = lut;
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
using ll = long long;
|
||||
|
||||
class Simulator;
|
||||
|
||||
class LUTCircuit {
|
||||
public:
|
||||
std::vector<LUT*> PIs;
|
||||
@ -12,12 +14,16 @@ 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_pick();
|
||||
LUT* ls_pick();
|
||||
void ls_flip(LUT *lut);
|
||||
void ls_main();
|
||||
|
||||
@ -25,6 +31,9 @@ void ls_main();
|
||||
|
||||
int check();
|
||||
|
||||
|
||||
Simulator *simulator;
|
||||
|
||||
};
|
||||
|
||||
class Circuit {
|
||||
|
124
src/ls.cpp
124
src/ls.cpp
@ -1,6 +1,69 @@
|
||||
#include <set>
|
||||
|
||||
#include "circuit.h"
|
||||
#include "paras.h"
|
||||
#include "simulator.h"
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
return pick;
|
||||
}
|
||||
|
||||
void LUTCircuit::ls_flip(LUT *lut) {
|
||||
|
||||
@ -8,6 +71,8 @@ void LUTCircuit::ls_flip(LUT *lut) {
|
||||
lut->value = !lut->value;
|
||||
if(!lut->isPI) lut->vsat = !lut->vsat;
|
||||
|
||||
lut->tabu = lut->vunat_cost + step;
|
||||
|
||||
for(LUT* out : lut->fanouts) {
|
||||
out->vsat = (out->cal_value() == out->value);
|
||||
}
|
||||
@ -35,6 +100,24 @@ void LUTCircuit::ls_flip(LUT *lut) {
|
||||
}
|
||||
}
|
||||
|
||||
void LUTCircuit::ls_update() {
|
||||
|
||||
std::unordered_set<LUT*> need_up;
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
for(LUT* lut : need_up) {
|
||||
lut->cal_score();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LUTCircuit::ls_main() {
|
||||
printf("====== local search start ======\n");
|
||||
|
||||
@ -86,14 +169,21 @@ 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("rg: %d %d\n", lut->reigon.size(), lut->update_reigon.size());
|
||||
}
|
||||
|
||||
printf("generating initial solution ...\n");
|
||||
|
||||
for(LUT* lut : luts) {
|
||||
lut->up_cost = 1;
|
||||
|
||||
lut->vunat_cost = 1;
|
||||
if(lut->isPI) {
|
||||
lut->vunat_cost = OPT(vsat_inc) * 100;
|
||||
}
|
||||
|
||||
lut->is_good_var = 0;
|
||||
lut->tabu = 0;
|
||||
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;
|
||||
@ -119,12 +209,14 @@ void LUTCircuit::ls_main() {
|
||||
lut->cal_score();
|
||||
}
|
||||
|
||||
step = 0;
|
||||
|
||||
print();
|
||||
|
||||
int seed = time(0);
|
||||
srand(1689658115);
|
||||
|
||||
int T = 10000;
|
||||
int T = 100000;
|
||||
while(T--) {
|
||||
|
||||
if(T % 1000 == 0) {
|
||||
@ -135,23 +227,43 @@ void LUTCircuit::ls_main() {
|
||||
|
||||
// print();
|
||||
|
||||
LUT* pick = luts[rand() % luts.size()];
|
||||
LUT* pick = ls_pick();
|
||||
// pick->cal_score();
|
||||
|
||||
// printf(">>>> flip: %s\n", pick->name);
|
||||
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);
|
||||
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);
|
||||
|
@ -60,7 +60,9 @@ int LUT::cal_value() {
|
||||
return value_table[input];
|
||||
}
|
||||
|
||||
LUT::LUT(Gate *gate):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()) {
|
||||
|
||||
C = circuit;
|
||||
|
||||
isPI = gate->isPI;
|
||||
isPO = gate->isPO;
|
||||
|
90
src/lut.h
90
src/lut.h
@ -1,66 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
class LUTCircuit;
|
||||
|
||||
#include "gate.h"
|
||||
|
||||
class LUT {
|
||||
public:
|
||||
LUT(Gate *gate, LUTCircuit *circuit);
|
||||
|
||||
LUT(Gate *gate);
|
||||
LUTCircuit *C;
|
||||
|
||||
Gate* gate;
|
||||
Gate *gate;
|
||||
|
||||
bool isPI, isPO;
|
||||
bool isPI, isPO;
|
||||
|
||||
std::vector<LUT*> fanins;
|
||||
std::vector<LUT *> fanins;
|
||||
|
||||
std::vector<LUT*> fanouts;
|
||||
std::vector<LUT *> fanouts;
|
||||
|
||||
std::vector<LUT*> reigon;
|
||||
std::vector<LUT*> update_reigon;
|
||||
std::vector<LUT *> reigon;
|
||||
std::vector<LUT *> update_reigon;
|
||||
|
||||
std::vector<LUT*> add_update_to_this;
|
||||
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;
|
||||
|
||||
std::unordered_map<Gate*, int> input_id;
|
||||
std::unordered_map<Gate *, int> input_id;
|
||||
|
||||
int& value;
|
||||
const char* name;
|
||||
int &value;
|
||||
const char *name;
|
||||
|
||||
int *value_table;
|
||||
int *value_table;
|
||||
|
||||
struct FaultInfo {
|
||||
int fd[2];
|
||||
int fpl[2];
|
||||
} **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;
|
||||
struct FaultInfo {
|
||||
int fd[2];
|
||||
int fpl[2];
|
||||
} **fault_table;
|
||||
|
||||
int cal_value();
|
||||
void cal_fault_info(int *t_fd, int* t_fpl);
|
||||
void get_fault_info(Gate* gate, int *t_fd, int* t_fpl);
|
||||
std::vector<FaultInfo *> fault_info;
|
||||
|
||||
// score
|
||||
int score;
|
||||
int score_value_unsatisfied_cost;
|
||||
int score_fault_detected_weight;
|
||||
int score_fault_propagated_weight;
|
||||
int score_fault_update_cost;
|
||||
std::unordered_set<LUT *> update_luts;
|
||||
|
||||
void cal_score();
|
||||
void cal_update();
|
||||
|
||||
void init_lookup_table();
|
||||
|
||||
// local search
|
||||
|
||||
bool vsat, vunat_cost;
|
||||
bool uptag, up_cost;
|
||||
int fd[2];
|
||||
int fpl[2];
|
||||
int is_good_var;
|
||||
int tabu;
|
||||
|
||||
int cal_value();
|
||||
void cal_fault_info(int *t_fd, int *t_fpl);
|
||||
void get_fault_info(Gate *gate, int *t_fd, int *t_fpl);
|
||||
|
||||
// score
|
||||
int score;
|
||||
int score_value_unsatisfied_cost;
|
||||
int score_fault_detected_weight;
|
||||
int score_fault_propagated_weight;
|
||||
int score_fault_update_cost;
|
||||
|
||||
void cal_score();
|
||||
void cal_update();
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "circuit.h"
|
||||
#include "simulator.h"
|
||||
#include "paras.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@ -9,13 +10,17 @@ int main(int argc, char *argv[]) {
|
||||
srand(19260817);
|
||||
|
||||
Circuit *circuit = new Circuit();
|
||||
Simulator* simulator = new Simulator();
|
||||
|
||||
printf("parsing file %s ...\n", OPT(instance).c_str());
|
||||
circuit->parse_from_file(OPT(instance).c_str());
|
||||
simulator->parse_from_file(OPT(instance).c_str());
|
||||
circuit->init_topo_index();
|
||||
simulator->init_topo_index();
|
||||
|
||||
printf("building lut circuit ...\n");
|
||||
LUTCircuit *C = circuit->build_lut_circuit();
|
||||
C->simulator = simulator;
|
||||
|
||||
printf("====== Circuit Statistics ====== \n");
|
||||
printf("PI:\t%ld\n", circuit->PIs.size());
|
||||
|
@ -7,7 +7,10 @@
|
||||
|
||||
// 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( 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")
|
||||
|
||||
// name, short-name, must-need, default, comments
|
||||
#define STR_PARAS \
|
||||
|
@ -76,7 +76,6 @@ void Circuit::parse_from_file(const char *filename) {
|
||||
gate->isPI = false;
|
||||
gate->isPO = false;
|
||||
|
||||
|
||||
for(auto &in : ins) {
|
||||
if(!name2gate.count(in)) {
|
||||
printf("Error while reading file: gate %s used before defination.\n", in.c_str());
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "lut.h"
|
||||
|
||||
|
||||
#include "circuit.h"
|
||||
|
||||
void LUT::cal_update() {
|
||||
|
||||
@ -55,6 +54,11 @@ void LUT::cal_update() {
|
||||
}
|
||||
|
||||
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() {
|
||||
@ -206,4 +210,9 @@ 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);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
#include "simulator.h"
|
||||
|
||||
void Simulator::simulate(std::vector<LUT*> &inputs, int &score) {
|
||||
|
||||
assert(inputs.size() == this->PIs.size());
|
||||
|
||||
for(int i=0; i<inputs.size(); i++) {
|
||||
PIs[i]->value = inputs[i]->value;
|
||||
}
|
||||
|
||||
for(auto gate : gates) {
|
||||
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);
|
||||
}
|
||||
|
||||
score = 0;
|
||||
|
||||
for(auto gate : gates) {
|
||||
if(gate->fault_detected[0] || gate->fault_detected[1]) {
|
||||
score++;
|
||||
}
|
||||
}
|
||||
}
|
8
src/simulator.h
Normal file
8
src/simulator.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "circuit.h"
|
||||
|
||||
class Simulator : public Circuit {
|
||||
public:
|
||||
void simulate(std::vector<LUT*> &inputs, int &score);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user