#include #include "lut.h" #include "paras.h" void LUT::get_fault_info(Gate* gate, int *t_fd, int* t_fpl) { } void LUT::cal_fault_info(int *fd, int* fpl) { fd[0] = fd[1] = fpl[0] = fpl[1] = 0; if(isPO) { fd[0] = value; fd[1] = !value; return; } for(int i=0; ivsat) continue; FaultInfo* info = nullptr; int input = 0; for(int j=0; jfanins.size(); j++) { if(out->fanins[j] == this) { info = out->fault_table[j]; } input |= (out->fanins[j]->value << j); } input <<= 1; input |= out->value; assert(info != nullptr); int t_fd[2], t_fpl[2]; t_fd[0] = info[input].fd[0] && out->fd[!value]; t_fd[1] = info[input].fd[1] && out->fd[!value]; t_fpl[0] = info[input].fpl[0] + info[input].fd[0] * out->fpl[!value]; t_fpl[1] = info[input].fpl[1] + info[input].fd[1] * out->fpl[!value]; fd[0] = std::max(fd[0], t_fd[0]); fd[1] = std::max(fd[1], t_fd[1]); fpl[0] = std::max(fpl[0], t_fpl[0]); fpl[1] = std::max(fpl[1], t_fpl[1]); } } int LUT::cal_value() { if(isPI) return value; int input = 0; for(int i=0; ivalue << i); } return value_table[input]; } LUT::LUT(Gate *gate, LUTCircuit *circuit):gate(gate), value(gate->value), name(gate->name.c_str()) { C = circuit; isPI = gate->isPI; isPO = gate->isPO; inner_gates.push_back(gate); std::set fanins; for(Gate* g : gate->fanins) { fanins.insert(g); // printf("init fanins: %s\n", g->name.c_str()); } while(true) { std::vector candidates; for(Gate* fanin : fanins) { if(fanin->fanouts.size() >= 2) continue; if(fanin->isPI) continue; int add = 0; for(Gate* in : fanin->fanins) { if(fanins.count(in) == 0) { add++; } } if(fanins.size() - 1 + add <= OPT(lut)) { candidates.push_back(fanin); } } if(candidates.size() == 0) break; Gate* random_gate = candidates[rand()%candidates.size()]; inner_gates.push_back(random_gate); fanins.erase(random_gate); for(Gate* in : random_gate->fanins) { fanins.insert(in); } } for(Gate* in : fanins) { __gate_fanins.push_back(in); } } void LUT::init_lookup_table() { value_table = new int[1 << fanins.size()]; fault_table = new FaultInfo *[fanins.size() + inner_gates.size()]; for (int i = 0; i < (fanins.size() + inner_gates.size()); i++) { fault_table[i] = new FaultInfo[1 << (fanins.size() + 1)]; } std::unordered_map gate_to_index; for(int i=0; igate] = i; } for(int i=0; igate->value = (i >> j) & 1; } for (Gate *g : inner_gates) { g->value = g->cal_value(); } assert(inner_gates[inner_gates.size() - 1] == gate); value_table[i] = gate->value; gate->value = 0; gate->fault_detected[0] = 0; gate->fault_detected[1] = 1; gate->fault_propagated_len[0] = 0; gate->fault_propagated_len[1] = 0; // continue; std::queue q; q.push(gate); while (!q.empty()) { Gate *g = q.front(); q.pop(); fault_table[gate_to_index[g]][(i<<1)|gate->value].fd[0] = g->fault_detected[0]; fault_table[gate_to_index[g]][(i<<1)|gate->value].fd[1] = g->fault_detected[1]; fault_table[gate_to_index[g]][(i<<1)|gate->value].fpl[0] = g->fault_propagated_len[0]; fault_table[gate_to_index[g]][(i<<1)|gate->value].fpl[1] = g->fault_propagated_len[1]; for (Gate *fanin : g->fanins) { fanin->fault_detected[0] = fanin->cal_fault_detected(0); fanin->fault_detected[1] = fanin->cal_fault_detected(1); fanin->fault_propagated_len[0] = fanin->cal_propagate_len(0); fanin->fault_propagated_len[1] = fanin->cal_propagate_len(1); if(gate_to_index.count(fanin)) q.push(fanin); } } gate->value = 1; gate->fault_detected[0] = 1; gate->fault_detected[1] = 0; gate->fault_propagated_len[0] = 0; gate->fault_propagated_len[1] = 0; q.push(gate); while (!q.empty()) { Gate *g = q.front(); q.pop(); fault_table[gate_to_index[g]][(i<<1)|gate->value].fd[0] = g->fault_detected[0]; fault_table[gate_to_index[g]][(i<<1)|gate->value].fd[1] = g->fault_detected[1]; fault_table[gate_to_index[g]][(i<<1)|gate->value].fpl[0] = g->fault_propagated_len[0]; fault_table[gate_to_index[g]][(i<<1)|gate->value].fpl[1] = g->fault_propagated_len[1]; for (Gate *fanin : g->fanins) { fanin->fault_detected[0] = fanin->cal_fault_detected(0); fanin->fault_detected[1] = fanin->cal_fault_detected(1); fanin->fault_propagated_len[0] = fanin->cal_propagate_len(0); fanin->fault_propagated_len[1] = fanin->cal_propagate_len(1); if(gate_to_index.count(fanin)) q.push(fanin); } } } }