增加仿真的步骤
This commit is contained in:
parent
69be6704ed
commit
b2df76e1de
10
circuit.h
10
circuit.h
@ -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
13
ls.cpp
@ -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
150
simulator.cpp
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user