atpg-ls/circuit.h

130 lines
2.3 KiB
C
Raw Normal View History

2023-02-12 18:14:12 +08:00
#pragma once
#include <string>
#include <vector>
#include <unordered_map>
2023-02-23 11:00:24 +08:00
#include <unordered_set>
2023-02-19 19:42:50 +08:00
#include <queue>
2023-02-20 13:08:25 +08:00
using ll = long long;
class Gate {
public:
2023-02-20 13:08:25 +08:00
int id;
2023-03-09 02:51:10 +00:00
int level;
std::string name;
2023-02-19 19:42:50 +08:00
enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT } type;
2023-02-12 18:14:12 +08:00
int value;
2023-02-19 19:42:50 +08:00
bool sa[2];
bool stem;
bool isPI;
bool isPO;
2023-03-06 11:05:30 +00:00
int fault_propagate_len[2];
2023-02-19 19:42:50 +08:00
std::vector<Gate*> pre_stems;
2023-02-21 19:07:40 +08:00
std::vector<Gate*> suc_stems;
2023-02-19 19:42:50 +08:00
std::vector<Gate*> outputs;
std::vector<Gate*> inputs;
2023-02-19 19:42:50 +08:00
bool is_propagated();
int cal_value();
2023-03-02 08:17:53 +00:00
bool cal_sa(bool x);
2023-03-06 11:05:30 +00:00
bool is_detected(Gate* one_of_input);
int cal_propagate_len(bool x);
};
2023-02-16 18:51:31 +08:00
class Fault {
public:
Gate* gate;
enum Type { SA0, SA1 } type;
2023-02-20 13:08:25 +08:00
Fault(Gate* gate, Type type):gate(gate),type(type) {}
2023-02-16 18:51:31 +08:00
};
class Circuit {
public:
std::vector<Gate*> PIs;
std::vector<Gate*> POs;
2023-02-12 16:22:32 +08:00
std::vector<Gate*> gates;
2023-02-19 19:42:50 +08:00
std::vector<Gate*> stems; // PI + stems
2023-02-16 18:51:31 +08:00
std::unordered_map<std::string, Gate*> name2gate;
2023-02-19 19:42:50 +08:00
std::queue<Gate*> tmp;
std::unordered_map<Gate*, bool> tmp_used;
void parse_from_file(const char *filename);
2023-02-19 19:42:50 +08:00
void print_gates();
bool is_valid_circuit();
2023-02-16 18:51:31 +08:00
void init_topo_index();
2023-03-09 02:51:10 +00:00
int MAX_GATE_LEVEL;
void init_gate_level();
2023-02-16 18:51:31 +08:00
void init_stems();
// local search
2023-02-19 19:42:50 +08:00
2023-02-23 11:00:24 +08:00
bool local_search(std::unordered_set<Fault*> &faults);
2023-02-16 18:51:31 +08:00
2023-02-20 13:08:25 +08:00
// incremental flip struct
2023-02-21 19:07:40 +08:00
2023-02-23 11:00:24 +08:00
const double SP = 0.01;
2023-02-21 19:07:40 +08:00
const int FLIP_INC = 1;
const int FLIP_WEIGHT_MAX = 1e9;
int* CC;
2023-02-20 13:08:25 +08:00
ll flip_total_weight;
2023-02-21 19:07:40 +08:00
int flip_total_cnt;
2023-02-20 13:08:25 +08:00
int* flip_weight;
int* flip_need_update;
std::vector<Gate*> flip_update_queue;
// incremental stem struct
2023-03-09 13:49:18 +08:00
int STEM_INC = 0;
2023-02-21 19:07:40 +08:00
const int STEM_WEIGHT_MAX = 1e9;
2023-02-20 13:08:25 +08:00
ll stem_total_weight;
2023-02-21 19:07:40 +08:00
int stem_total_cnt;
2023-02-20 13:08:25 +08:00
int* stem_weight;
int* stem_satisfied;
2023-03-06 11:05:30 +00:00
int fault_propagate_tatal_len;
2023-03-11 07:02:02 +00:00
ll fault_propagate_score;
2023-03-06 11:05:30 +00:00
2023-02-21 19:07:40 +08:00
const int FAULT_INC = 1;
2023-02-23 11:00:24 +08:00
const int FAULT_WEIGHT_MAX = 20;
2023-02-20 13:08:25 +08:00
ll fault_total_weight;
2023-02-21 19:07:40 +08:00
int fault_total_cnt;
2023-02-20 13:08:25 +08:00
int** fault_weight;
int** fault_detected;
2023-02-16 18:51:31 +08:00
void ls_init_circuit();
2023-02-23 11:00:24 +08:00
void ls_init_weight(const std::unordered_set<Fault*> &faults);
2023-02-21 19:07:40 +08:00
void ls_update_weight();
2023-02-20 13:08:25 +08:00
void ls_init_data_structs();
2023-02-12 18:14:12 +08:00
2023-02-20 14:41:19 +08:00
void ls_block_recal(Gate* stem);
void ls_flip(Gate* stem);
void ls_update(Gate* stem);
2023-02-21 19:07:40 +08:00
ll ls_pick_score(Gate* stem);
ll ls_score();
2023-03-06 11:05:30 +00:00
int** simulate();
2023-03-11 07:02:02 +00:00
// time status
int flip_cnt = 0;
double flip_time = 0;
int update_cnt = 0;
double update_time = 0;
2023-05-05 02:40:33 +00:00
std::unordered_set<Gate*> stem_unsatisfied_set;
};