YOSYS_NAMESPACE_BEGIN
-int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr);
+struct CellCosts
+{
+ static const dict<RTLIL::IdString, int>& default_gate_cost() {
+ static const dict<RTLIL::IdString, int> db = {
+ { ID($_BUF_), 1 },
+ { ID($_NOT_), 2 },
+ { ID($_AND_), 4 },
+ { ID($_NAND_), 4 },
+ { ID($_OR_), 4 },
+ { ID($_NOR_), 4 },
+ { ID($_ANDNOT_), 4 },
+ { ID($_ORNOT_), 4 },
+ { ID($_XOR_), 5 },
+ { ID($_XNOR_), 5 },
+ { ID($_AOI3_), 6 },
+ { ID($_OAI3_), 6 },
+ { ID($_AOI4_), 7 },
+ { ID($_OAI4_), 7 },
+ { ID($_MUX_), 4 },
+ { ID($_NMUX_), 4 }
+ };
+ return db;
+ }
-int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> ¶meters = dict<RTLIL::IdString, RTLIL::Const>(),
- RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr);
+ static const dict<RTLIL::IdString, int>& cmos_gate_cost() {
+ static const dict<RTLIL::IdString, int> db = {
+ { ID($_BUF_), 1 },
+ { ID($_NOT_), 2 },
+ { ID($_AND_), 6 },
+ { ID($_NAND_), 4 },
+ { ID($_OR_), 6 },
+ { ID($_NOR_), 4 },
+ { ID($_ANDNOT_), 6 },
+ { ID($_ORNOT_), 6 },
+ { ID($_XOR_), 12 },
+ { ID($_XNOR_), 12 },
+ { ID($_AOI3_), 6 },
+ { ID($_OAI3_), 6 },
+ { ID($_AOI4_), 8 },
+ { ID($_OAI4_), 8 },
+ { ID($_MUX_), 12 },
+ { ID($_NMUX_), 10 }
+ };
+ return db;
+ }
-inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache)
-{
- return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache);
-}
+ dict<RTLIL::IdString, int> mod_cost_cache;
+ const dict<RTLIL::IdString, int> *gate_cost = nullptr;
+ Design *design = nullptr;
+
+ int get(RTLIL::IdString type) const
+ {
+ if (gate_cost && gate_cost->count(type))
+ return gate_cost->at(type);
+
+ log_warning("Can't determine cost of %s cell.\n", log_id(type));
+ return 1;
+ }
+
+ int get(RTLIL::Cell *cell)
+ {
+ if (gate_cost && gate_cost->count(cell->type))
+ return gate_cost->at(cell->type);
+
+ if (design && design->module(cell->type) && cell->parameters.empty())
+ {
+ RTLIL::Module *mod = design->module(cell->type);
+
+ if (mod->attributes.count(ID(cost)))
+ return mod->attributes.at(ID(cost)).as_int();
+
+ if (mod_cost_cache.count(mod->name))
+ return mod_cost_cache.at(mod->name);
+
+ int module_cost = 1;
+ for (auto c : mod->cells())
+ module_cost += get(c);
+
+ mod_cost_cache[mod->name] = module_cost;
+ return module_cost;
+ }
+
+ log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(cell->type), GetSize(cell->parameters));
+ return 1;
+ }
+};
YOSYS_NAMESPACE_END