带sim的版本

This commit is contained in:
YuhangQ 2023-07-31 05:55:25 +00:00
parent 4aa1c086b7
commit 535cc3bd81
15 changed files with 262 additions and 72 deletions

20
CMakeLists.txt Normal file
View 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})

BIN
atpg

Binary file not shown.

2
crun
View File

@ -10,6 +10,6 @@ if [ $? -ne 0 ]; then
else
clear
echo "========================"
time ./atpg -i $1 --lut 4
time ./atpg -i $1 --lut 8
fi

View File

@ -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);

View File

@ -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;

View File

@ -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 {

View File

@ -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);

View File

@ -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;

View File

@ -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();
};

View File

@ -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());

View File

@ -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 \

View File

@ -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());

View File

@ -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);
}
}

View File

@ -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
View File

@ -0,0 +1,8 @@
#pragma once
#include "circuit.h"
class Simulator : public Circuit {
public:
void simulate(std::vector<LUT*> &inputs, int &score);
};