增加仿真的步骤

This commit is contained in:
YuhangQ 2023-03-04 10:28:39 +00:00
parent 69be6704ed
commit b2df76e1de
4 changed files with 170 additions and 3 deletions

BIN
atpg

Binary file not shown.

View File

@ -80,18 +80,18 @@ void init_stems();
// local search
// shared info
static const int STEM_INC = 10;
static const int STEM_INC = 2;
static const int STEM_COST_MAX = 1e9;
static ll stem_total_cost;
static int stem_falsified_cnt;
static const int PROPAGATE_INC = 10;
static const int PROPAGATE_INC = 2;
static const int PROPAGATE_COST_MAX = 1e9;
static ll propagate_total_cost;
static int propagate_falsified_cnt;
static const int FAULT_INC = 1;
static const int FAULT_COST_MAX = 20;
static const int FAULT_COST_MAX = 1e9;
static ll fault_total_cost;
static int fault_falsified_cnt;
@ -116,4 +116,8 @@ void ls_update(Gate* stem);
ll ls_pick_score(Gate* stem, bool value, bool propagate);
ll ls_score();
// simulator
int** simulate();
};

13
ls.cpp
View File

@ -28,6 +28,19 @@ bool Circuit::local_search(std::unordered_set<Fault*> &faults) {
ls_update_weight();
picked_stem = ls_pick_falsified_var(value, propagate);
printf("[UP] propagate: %lld, stem: %lld, fault:%lld. propagate_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", propagate_total_cost, stem_total_cost, fault_total_cost, propagate_falsified_cnt, stem_falsified_cnt, fault_falsified_cnt);
int** sa = simulate();
int cnt = 0;
static int max_cnt = 0;
for(Fault* f : faults) {
if(sa[f->gate->id][f->type]) {
cnt++;
}
}
max_cnt = std::max(max_cnt, cnt);
printf("[SOL] detect-faults: %d max-faults: %d\n", cnt, max_cnt);
} else {
// printf("pick: %s value: %d propagate: %d\n", picked_stem->name.c_str(), value, propagate);
// printf("[LS] propagate: %lld, stem: %lld, fault:%lld. propagate_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", propagate_total_cost, stem_total_cost, fault_total_cost, propagate_falsified_cnt, stem_falsified_cnt, fault_falsified_cnt);

150
simulator.cpp Normal file
View File

@ -0,0 +1,150 @@
#include "circuit.h"
#include <assert.h>
#include <unordered_map>
int cal_value(Gate *g, int *value) {
int res;
switch(g->type) {
case Gate::NOT:
res = !value[g->inputs[0]->id];
break;
case Gate::BUF:
res = value[g->inputs[0]->id];
break;
case Gate::AND:
res = value[g->inputs[0]->id];
for(int i=1; i<g->inputs.size(); i++) {
res &= value[g->inputs[i]->id];
}
break;
case Gate::NAND:
res = value[g->inputs[0]->id];
for(int i=1; i<g->inputs.size(); i++) {
res &= value[g->inputs[i]->id];
}
res = !res;
break;
case Gate::OR:
res = value[g->inputs[0]->id];
for(int i=1; i<g->inputs.size(); i++) {
res |= value[g->inputs[i]->id];
}
break;
case Gate::NOR:
res = value[g->inputs[0]->id];
for(int i=1; i<g->inputs.size(); i++) {
res |= value[g->inputs[i]->id];
}
res = !res;
break;
case Gate::XOR:
res = value[g->inputs[0]->id];
for(int i=1; i<g->inputs.size(); i++) {
res ^= value[g->inputs[i]->id];
}
break;
case Gate::XNOR:
res = value[g->inputs[0]->id];
for(int i=1; i<g->inputs.size(); i++) {
res ^= value[g->inputs[i]->id];
}
res = !res;
break;
case Gate::INPUT:
res = value[g->id];
break;
default:
assert(false);
break;
}
return res;
}
bool cal_sa(Gate* g, bool x, int** sa, int *value) {
if(g->po) {
if(x == 0) return value[g->id];
else return !value[g->id];
}
bool sa0 = 0;
bool sa1 = 0;
for(Gate* out : g->outputs) {
if(!sa[out->id][0] && !sa[out->id][1]) continue;
if(cal_value(out, value) != value[out->id]) continue;
value[g->id] = !value[g->id];
bool detect = cal_value(out, value) != value[out->id];
value[g->id] = !value[g->id];
if(!detect) continue;
sa0 |= value[g->id];
sa1 |= !value[g->id];
}
if(x == 0) return sa0;
else return sa1;
}
int** Circuit::simulate() {
static bool init = false;
static int** sa = nullptr;
static int* value = nullptr;
if(!init) {
const int MAXN = gates.size() + 1;
init = true;
sa = new int*[MAXN];
for(int i=0; i<MAXN; i++) {
sa[i] = new int[2];
}
value = new int[MAXN];
}
// init PI
for(Gate* pi : PIs) {
value[pi->id] = pi->value;
}
for(Gate *g : gates) {
if(g->pi) continue;
value[g->id] = cal_value(g, value);
}
for(Gate *g : gates) {
assert(value[g->id] == cal_value(g, value));
}
std::queue<Gate*> q;
std::unordered_map<Gate*, int> topo;
// init PO
for(Gate* po : POs) {
sa[po->id][!value[po->id]] = 1;
sa[po->id][value[po->id]] = 0;
q.push(po);
}
while(!q.empty()) {
Gate* g = q.front();
q.pop();
for(Gate* in : g->inputs) {
if(++topo[in] == in->outputs.size()) {
sa[in->id][0] = cal_sa(in, 0, sa, value);
sa[in->id][1] = cal_sa(in, 1, sa, value);
q.push(in);
}
}
}
for(Gate* g : gates) {
assert(sa[g->id][0] == cal_sa(g, 0, sa, value));
assert(sa[g->id][1] == cal_sa(g, 1, sa, value));
}
return sa;
}