Ignore change on last edge
[yosys.git] / kernel / cost.h
index 41a09eb6334bdcd63a363adb5f7566a4e551c7f3..b81420af756b7bd2580efc86c1a6e44ad9cca93f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  yosys -- Yosys Open SYnthesis Suite
  *
- *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *  Copyright (C) 2012  Claire Xenia Wolf <claire@yosyshq.com>
  *
  *  Permission to use, copy, modify, and/or distribute this software for any
  *  purpose with or without fee is hereby granted, provided that the above
 
 YOSYS_NAMESPACE_BEGIN
 
-int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr);
-
-inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> &parameters = dict<RTLIL::IdString, RTLIL::Const>(),
-               RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr)
+struct CellCosts
 {
-       static dict<RTLIL::IdString, int> gate_cost = {
-               { "$_BUF_",    1 },
-               { "$_NOT_",    2 },
-               { "$_AND_",    4 },
-               { "$_NAND_",   4 },
-               { "$_OR_",     4 },
-               { "$_NOR_",    4 },
-               { "$_ANDNOT_", 4 },
-               { "$_ORNOT_",  4 },
-               { "$_XOR_",    8 },
-               { "$_XNOR_",   8 },
-               { "$_AOI3_",   6 },
-               { "$_OAI3_",   6 },
-               { "$_AOI4_",   8 },
-               { "$_OAI4_",   8 },
-               { "$_MUX_",    4 }
-       };
-
-       if (gate_cost.count(type))
-               return gate_cost.at(type);
-
-       if (parameters.empty() && design && design->module(type))
+       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;
+       }
+
+       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;
+       }
+
+       dict<RTLIL::IdString, int> mod_cost_cache;
+       const dict<RTLIL::IdString, int> *gate_cost = nullptr;
+       Design *design = nullptr;
+
+       int get(RTLIL::IdString type) const
        {
-               RTLIL::Module *mod = design->module(type);
+               if (gate_cost && gate_cost->count(type))
+                       return gate_cost->at(type);
 
-               if (mod->attributes.count("\\cost"))
-                       return mod->attributes.at("\\cost").as_int();
+               log_warning("Can't determine cost of %s cell.\n", log_id(type));
+               return 1;
+       }
 
-               dict<RTLIL::IdString, int> local_mod_cost_cache;
-               if (mod_cost_cache == nullptr)
-                       mod_cost_cache = &local_mod_cost_cache;
+       int get(RTLIL::Cell *cell)
+       {
+               if (gate_cost && gate_cost->count(cell->type))
+                       return gate_cost->at(cell->type);
 
-               if (mod_cost_cache->count(mod->name))
-                       return mod_cost_cache->at(mod->name);
+               if (design && design->module(cell->type) && cell->parameters.empty())
+               {
+                       RTLIL::Module *mod = design->module(cell->type);
 
-               int module_cost = 1;
-               for (auto c : mod->cells())
-                       module_cost += get_cell_cost(c, mod_cost_cache);
+                       if (mod->attributes.count(ID(cost)))
+                               return mod->attributes.at(ID(cost)).as_int();
 
-               (*mod_cost_cache)[mod->name] = module_cost;
-               return module_cost;
-       }
+                       if (mod_cost_cache.count(mod->name))
+                               return mod_cost_cache.at(mod->name);
 
-       log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(type), GetSize(parameters));
-       return 1;
-}
+                       int module_cost = 1;
+                       for (auto c : mod->cells())
+                               module_cost += get(c);
 
-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);
-}
+                       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