Move ConstEvalAig to aigerparse.cc
authorEddie Hung <eddie@fpgeh.com>
Thu, 13 Jun 2019 23:28:11 +0000 (16:28 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 13 Jun 2019 23:28:11 +0000 (16:28 -0700)
frontends/aiger/aigerparse.cc
kernel/consteval.h

index 42b3c7624f666b2ecb529f381da547f0233b0977..3b5f413df2ad87da3a1cc320dd729eb4e1421548 100644 (file)
 
 YOSYS_NAMESPACE_BEGIN
 
+struct ConstEvalAig
+{
+       RTLIL::Module *module;
+       dict<RTLIL::SigBit, RTLIL::Const> values_map;
+       SigSet<RTLIL::Cell*> sig2driver;
+       dict<SigBit, pool<RTLIL::SigBit>> sig2deps;
+
+       ConstEvalAig(RTLIL::Module *module) : module(module)
+       {
+               CellTypes ct;
+               ct.setup_internals();
+               ct.setup_stdcells();
+
+               for (auto &it : module->cells_) {
+                       if (!ct.cell_known(it.second->type))
+                               continue;
+                       for (auto &it2 : it.second->connections())
+                               if (ct.cell_output(it.second->type, it2.first))
+                                       sig2driver.insert(it2.second, it.second);
+               }
+       }
+
+       void clear()
+       {
+               values_map.clear();
+               sig2deps.clear();
+       }
+
+       void set(RTLIL::SigSpec sig, RTLIL::Const value)
+       {
+#ifndef NDEBUG
+               auto it = values_map.find(sig);
+               RTLIL::SigSpec current_val;
+               if (it != values_map.end())
+                       current_val = it->second;
+               for (int i = 0; i < GetSize(current_val); i++)
+                       log_assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]);
+#endif
+               for (int i = 0; i < GetSize(sig); i++)
+                       values_map[sig[i]] = value[i];
+       }
+
+       void set_incremental(RTLIL::SigSpec sig, RTLIL::Const value)
+       {
+               log_assert(GetSize(sig) == GetSize(value));
+
+               for (int i = 0; i < GetSize(sig); i++) {
+                       auto it = values_map.find(sig[i]);
+                       if (it != values_map.end()) {
+                               RTLIL::SigSpec current_val = it->second;
+                               if (current_val != value[i])
+                                       for (auto dep : sig2deps[sig[i]])
+                                               values_map.erase(dep);
+                               it->second = value[i];
+                       }
+                       else
+                               values_map[sig[i]] = value[i];
+               }
+       }
+
+       void compute_deps(RTLIL::SigBit output, const pool<RTLIL::SigBit> &inputs)
+       {
+               sig2deps[output].insert(output);
+
+               std::set<RTLIL::Cell*> driver_cells;
+               sig2driver.find(output, driver_cells);
+               for (auto cell : driver_cells) {
+                       RTLIL::SigBit sig_a = cell->getPort("\\A");
+                       sig2deps[sig_a].insert(sig2deps[output].begin(), sig2deps[output].end());
+                       if (!inputs.count(sig_a))
+                               compute_deps(sig_a, inputs);
+
+                       if (cell->type == "$_AND_") {
+                               RTLIL::SigSpec sig_b = cell->getPort("\\B");
+                               sig2deps[sig_b].insert(sig2deps[output].begin(), sig2deps[output].end());
+                               if (!inputs.count(sig_b))
+                                       compute_deps(sig_b, inputs);
+                       }
+                       else if (cell->type == "$_NOT_") {
+                       }
+                       else log_abort();
+               }
+       }
+
+       bool eval(RTLIL::Cell *cell)
+       {
+               RTLIL::SigSpec sig_y = cell->getPort("\\Y");
+               auto it = values_map.find(sig_y);
+               if (it != values_map.end())
+                       sig_y = it->second;
+               if (sig_y.is_fully_const())
+                       return true;
+
+               RTLIL::SigSpec sig_a = cell->getPort("\\A");
+               if (sig_a.size() > 0 && !eval(sig_a))
+                       return false;
+
+               RTLIL::Const eval_ret;
+               if (cell->type == "$_NOT_") {
+                       if (sig_a == RTLIL::S0) eval_ret = RTLIL::S1;
+                       else if (sig_a == RTLIL::S1) eval_ret = RTLIL::S0;
+               }
+               else if (cell->type == "$_AND_") {
+                       if (sig_a == RTLIL::S0) {
+                               eval_ret = RTLIL::S0;
+                               goto eval_end;
+                       }
+
+                       {
+                               RTLIL::SigSpec sig_b = cell->getPort("\\B");
+                               if (sig_b.size() > 0 && !eval(sig_b))
+                                       return false;
+                               if (sig_b == RTLIL::S0) {
+                                       eval_ret = RTLIL::S0;
+                                       goto eval_end;
+                               }
+
+                               if (sig_a != RTLIL::State::S1 || sig_b != RTLIL::State::S1) {
+                                       eval_ret = RTLIL::State::Sx;
+                                       goto eval_end;
+                               }
+
+                               eval_ret = RTLIL::State::S1;
+                       }
+               }
+               else log_abort();
+
+eval_end:
+               set(sig_y, eval_ret);
+               return true;
+       }
+
+       bool eval(RTLIL::SigSpec &sig)
+       {
+               auto it = values_map.find(sig);
+               if (it != values_map.end())
+                       sig = it->second;
+               if (sig.is_fully_const())
+                       return true;
+
+               std::set<RTLIL::Cell*> driver_cells;
+               sig2driver.find(sig, driver_cells);
+               for (auto cell : driver_cells)
+                       if (!eval(cell))
+                               return false;
+
+               it = values_map.find(sig);
+               if (it != values_map.end())
+                       sig = it->second;
+               if (sig.is_fully_const())
+                       return true;
+
+               return false;
+       }
+};
+
 AigerReader::AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name, std::string map_filename, bool wideports)
        : design(design), f(f), clk_name(clk_name), map_filename(map_filename), wideports(wideports)
 {
@@ -249,13 +405,15 @@ void AigerReader::parse_xaiger()
                                                log_assert(wire);
                                                input_sig.append(wire);
                                        }
+                                       ce.clear();
+                                       ce.compute_deps(output_sig, input_sig.to_sigbit_pool());
                                        RTLIL::Const lut_mask(RTLIL::State::Sx, 1 << input_sig.size());
                                        for (int j = 0; j < (1 << cutLeavesM); ++j) {
-                                               ce.clear();
-                                               ce.set(input_sig, RTLIL::Const{j, static_cast<int>(cutLeavesM)});
+                                               int gray = j ^ (j >> 1);
+                                               ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast<int>(cutLeavesM)});
                                                RTLIL::SigSpec o(output_sig);
                                                ce.eval(o);
-                                               lut_mask[j] = o.as_const()[0];
+                                               lut_mask[gray] = o.as_const()[0];
                                        }
                                        RTLIL::Cell *output_cell = module->cell(stringf("\\__%d__$and", rootNodeID));
                                        log_assert(output_cell);
index e0131b23379d58565b2b1feacb71c28dda00c825..154373a8deeef29bb2223ae6029d4ffeb167a31c 100644 (file)
@@ -390,163 +390,6 @@ struct ConstEval
        }
 };
 
-struct ConstEvalAig
-{
-       RTLIL::Module *module;
-       //SigMap assign_map;
-       SigMap values_map;
-       //SigPool stop_signals;
-       SigSet<RTLIL::Cell*> sig2driver;
-       //std::set<RTLIL::Cell*> busy;
-       //std::vector<SigMap> stack;
-       //RTLIL::State defaultval;
-
-       ConstEvalAig(RTLIL::Module *module /*, RTLIL::State defaultval = RTLIL::State::Sm*/) : module(module) /*, assign_map(module), defaultval(defaultval)*/
-       {
-               CellTypes ct;
-               ct.setup_internals();
-               ct.setup_stdcells();
-
-               for (auto &it : module->cells_) {
-                       if (!ct.cell_known(it.second->type))
-                               continue;
-                       for (auto &it2 : it.second->connections())
-                               if (ct.cell_output(it.second->type, it2.first))
-                                       sig2driver.insert(/*assign_map*/(it2.second), it.second);
-               }
-       }
-
-       void clear()
-       {
-               values_map.clear();
-               //stop_signals.clear();
-       }
-
-       //void push()
-       //{
-       //      stack.push_back(values_map);
-       //}
-
-       //void pop()
-       //{
-       //      values_map.swap(stack.back());
-       //      stack.pop_back();
-       //}
-
-       void set(RTLIL::SigSpec sig, RTLIL::Const value)
-       {
-               //assign_map.apply(sig);
-#ifndef NDEBUG
-               RTLIL::SigSpec current_val = values_map(sig);
-               for (int i = 0; i < GetSize(current_val); i++)
-                       log_assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]);
-#endif
-               values_map.add(sig, RTLIL::SigSpec(value));
-       }
-
-       //void stop(RTLIL::SigSpec sig)
-       //{
-       //      assign_map.apply(sig);
-       //      stop_signals.add(sig);
-       //}
-
-       bool eval(RTLIL::Cell *cell /*, RTLIL::SigSpec &undef*/)
-       {
-               RTLIL::SigSpec sig_y = values_map(/*assign_map*/(cell->getPort("\\Y")));
-               if (sig_y.is_fully_const())
-                       return true;
-
-               RTLIL::SigSpec sig_a = cell->getPort("\\A");
-               if (sig_a.size() > 0 && !eval(sig_a /*, undef, cell*/))
-                       return false;
-
-               RTLIL::Const eval_ret;
-               if (cell->type == "$_NOT_") {
-                       if (sig_a == RTLIL::S0) eval_ret = RTLIL::S1;
-                       else if (sig_a == RTLIL::S1) eval_ret = RTLIL::S0;
-               }
-               else if (cell->type == "$_AND_") {
-                       if (sig_a == RTLIL::S0) {
-                               eval_ret = RTLIL::S0;
-                               goto eval_end;
-                       }
-
-                       {
-                               RTLIL::SigSpec sig_b = cell->getPort("\\B");
-                               if (sig_b.size() > 0 && !eval(sig_b /*, undef, cell*/))
-                                       return false;
-                               if (sig_b == RTLIL::S0) {
-                                       eval_ret = RTLIL::S0;
-                                       goto eval_end;
-                               }
-
-                               if (sig_a != RTLIL::State::S1 || sig_b != RTLIL::State::S1) {
-                                       eval_ret = RTLIL::State::Sx;
-                                       goto eval_end;
-                               }
-
-                               eval_ret = RTLIL::State::S1;
-                       }
-               }
-               else log_abort();
-
-
-eval_end:
-               set(sig_y, eval_ret);
-               return true;
-       }
-
-       bool eval(RTLIL::SigSpec &sig /*, RTLIL::SigSpec &undef, RTLIL::Cell *busy_cell = NULL*/)
-       {
-               //assign_map.apply(sig);
-               values_map.apply(sig);
-
-               if (sig.is_fully_const())
-                       return true;
-
-               //if (stop_signals.check_any(sig)) {
-               //      undef = stop_signals.extract(sig);
-               //      return false;
-               //}
-
-               //if (busy_cell) {
-               //      if (busy.count(busy_cell) > 0) {
-               //              undef = sig;
-               //              return false;
-               //      }
-               //      busy.insert(busy_cell);
-               //}
-
-               std::set<RTLIL::Cell*> driver_cells;
-               sig2driver.find(sig, driver_cells);
-               for (auto cell : driver_cells) {
-                       if (!eval(cell /*, undef*/)) {
-                               //if (busy_cell)
-                               //      busy.erase(busy_cell);
-                               return false;
-                       }
-               }
-
-               //if (busy_cell)
-               //      busy.erase(busy_cell);
-
-               values_map.apply(sig);
-               if (sig.is_fully_const())
-                       return true;
-
-               //for (auto &c : sig.chunks())
-               //      if (c.wire != NULL)
-               //              undef.append(c);
-               return false;
-       }
-
-       //bool eval(RTLIL::SigSpec &sig)
-       //{
-       //      RTLIL::SigSpec undef;
-       //      return eval(sig, undef);
-       //}
-};
-
 YOSYS_NAMESPACE_END
 
 #endif