#include "circuit.h" #include #include #include #include "assert.h" #include "clause.h" void Circuit::init_topo_index() { int topo = 1; std::queue q; std::unordered_map ins; // 计算正向拓扑序 for(auto in : PIs) { in->id = topo++; q.push(in); } while(!q.empty()) { Gate* g = q.front(); q.pop(); for(Gate* out : g->fan_outs) { ins[out]++; if(ins[out] == out->fan_ins.size()) { out->id = topo++; q.push(out); } } } for(Gate* g : gates) { id2gate[g->id] = g; } // 计算反向拓扑序 topo = 1; std::unordered_map outs; for(auto out : POs) { out->rtopo = topo++; q.push(out); } while(!q.empty()) { Gate* g = q.front(); q.pop(); rtopo_gates.push_back(g); for(Gate* in : g->fan_ins) { outs[in]++; if(outs[in] == in->fan_outs.size()) { in->rtopo = topo++; q.push(in); } } } } void Circuit::print_circuit() { static const char* type2name[9] = {"AND", "NAND", "OR", "NOR", "XOR", "XNOR", "NOT", "BUF", "IN"}; for(Gate* gate : gates) { printf("Gate: %3s (t:%4s v:%d ss:%d pi:%d po:%d s:%d p:%d s0:%d s1:%d fpl0:%d fpl1:%d) Inputs:", gate->name.c_str(), type2name[gate->type], gate->value, gate->stem_satisfied, gate->pi, gate->po, gate->stem, gate->propagate, gate->fault_detected[0], gate->fault_detected[1], gate->fault_propagate_length[0], gate->fault_propagate_length[1]); for(Gate* in : gate->fan_ins) { printf(" %s(%d)", in->name.c_str(), gate->is_detected(in)); } printf("\n"); } } bool Circuit::is_valid_circuit() { ll stem_total_cost = 0; ll fault_total_weight = 0; int stem_total_cnt = 0; int fault_total_cnt = 0; ll fault_propagate_score = 0; //printf("flip: %d, stem: %d, fault:%d\n", flip_total_weight, stem_total_weight, fault_total_weight); for(Gate* g : gates) { if(g->propagate != (g->fault_detected[0] || g->fault_detected[1])) { printf("Gate: %s Error: propagte varible wrong\n", g->name.c_str()); return false; } if(g->stem && (g->recal_value() == g->value) != g->stem_satisfied) { printf("Gate: %s Error: stem satisfied wrong\n", g->name.c_str()); return false; } if(!g->stem && g->recal_value() != g->value) { printf("Gate: %s Error: value cal wrong\n", g->name.c_str()); return false; } int fpl[2]; g->recal_propagate_len(fpl); if(g->fault_propagate_length[0] != fpl[0] || g->fault_propagate_length[1] != fpl[1]) { printf("Gate: %s Error: fpl cal wrong\n", g->name.c_str()); return false; } bool fd[2]; g->recal_fault(fd); if(g->fault_detected[0] != fd[0] || g->fault_detected[1] != fd[1]) { printf("Gate: %s Error: fpl cal wrong\n", g->name.c_str()); return false; } if(g->stem && g->recal_value() != g->value) { stem_total_cost += g->stem_weight; } if(g->stem && g->recal_value() == g->value) { stem_total_cnt++; } fault_propagate_score += g->fault_propagate_length[0] * g->fault_weight[0]; fault_propagate_score += g->fault_propagate_length[1] * g->fault_weight[1]; if(g->fault_detected[0]) { fault_total_weight += g->fault_weight[0]; fault_total_cnt += 1; } if(g->fault_detected[1]) { fault_total_weight += g->fault_weight[1]; fault_total_cnt += 1; } } assert(this->stem_total_cost == stem_total_cost); //assert(this->fault_total_weight == fault_total_weight); assert(this->stem_total_cnt == stem_total_cnt); assert(this->fault_total_cnt == fault_total_cnt); assert(this->fault_propagate_score == fault_propagate_score); return true; }