diff --git a/kernel/cost.cc b/kernel/cost.cc index 7fe21b97b3b..1c207ee906a 100644 --- a/kernel/cost.cc +++ b/kernel/cost.cc @@ -136,7 +136,7 @@ unsigned int CellCosts::get(RTLIL::Cell *cell) { // simple 1-bit cells - if (gate_type_cost().count(cell->type)) + if (cmos_gate_cost().count(cell->type)) return 1; if (design_ && design_->module(cell->type) && cell->parameters.empty()) { diff --git a/kernel/cost.h b/kernel/cost.h index 3caeb3b3f48..48ae0e9cace 100644 --- a/kernel/cost.h +++ b/kernel/cost.h @@ -27,21 +27,17 @@ YOSYS_NAMESPACE_BEGIN struct CellCosts { - enum CostKind { - DEFAULT, - CMOS, - }; - private: dict mod_cost_cache_; - CostKind kind_; Design *design_ = nullptr; public: - CellCosts(CellCosts::CostKind kind, RTLIL::Design *design) : kind_(kind), design_(design) { } + CellCosts(RTLIL::Design *design) : design_(design) { } - const dict& gate_type_cost() { - static const dict default_gate_db = { + static const dict& default_gate_cost() { + // Default size heuristics for several common PDK standard cells + // used by abc and stat + static const dict db = { { ID($_BUF_), 1 }, { ID($_NOT_), 2 }, { ID($_AND_), 4 }, @@ -59,8 +55,13 @@ struct CellCosts { ID($_MUX_), 4 }, { ID($_NMUX_), 4 }, }; + return db; + } - static const dict cmos_transistors_db = { + static const dict& cmos_gate_cost() { + // Estimated CMOS transistor counts for several common PDK standard cells + // used by stat and optionally by abc + static const dict db = { { ID($_BUF_), 1 }, { ID($_NOT_), 2 }, { ID($_AND_), 6 }, @@ -80,14 +81,7 @@ struct CellCosts { ID($_DFF_P_), 16 }, { ID($_DFF_N_), 16 }, }; - switch (kind_) { - case DEFAULT: - return default_gate_db; - case CMOS: - return cmos_transistors_db; - default: - log_assert(false && "Unreachable: Invalid cell cost kind\n"); - } + return db; } unsigned int get(RTLIL::Module *mod); diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 1761ddf6892..379ce209790 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -222,16 +222,14 @@ struct statdata_t unsigned int cmos_transistor_count(bool *tran_cnt_exact) { unsigned int tran_cnt = 0; - auto cost_kind = CellCosts::CMOS; - CellCosts costs(cost_kind, nullptr); - auto cell_type_cost = costs.gate_type_cost(); + auto &gate_costs = CellCosts::cmos_gate_cost(); for (auto it : num_cells_by_type) { auto ctype = it.first; auto cnum = it.second; - if (cell_type_cost.count(ctype)) - tran_cnt += cnum * cell_type_cost.at(ctype); + if (gate_costs.count(ctype)) + tran_cnt += cnum * gate_costs.at(ctype); else *tran_cnt_exact = false; } diff --git a/passes/hierarchy/keep_hierarchy.cc b/passes/hierarchy/keep_hierarchy.cc index 27864a4c5f4..49e3e3fb5a7 100644 --- a/passes/hierarchy/keep_hierarchy.cc +++ b/passes/hierarchy/keep_hierarchy.cc @@ -53,7 +53,7 @@ struct KeepHierarchyPass : public Pass { } extra_args(args, argidx, design); - CellCosts costs(CellCosts::DEFAULT, design); + CellCosts costs(design); for (auto module : design->selected_modules()) { if (min_cost) { diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index be02a781d65..42287966288 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1047,9 +1047,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin { log_header(design, "Executing ABC.\n"); - auto cost_kind = cmos_cost ? CellCosts::CMOS : CellCosts::DEFAULT; - CellCosts costs(cost_kind, design); - auto cell_type_cost = costs.gate_type_cost(); + auto &cell_cost = cmos_cost ? CellCosts::cmos_gate_cost() : CellCosts::default_gate_cost(); buffer = stringf("%s/stdcells.genlib", tempdir_name.c_str()); f = fopen(buffer.c_str(), "wt"); @@ -1057,42 +1055,42 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); fprintf(f, "GATE ZERO 1 Y=CONST0;\n"); fprintf(f, "GATE ONE 1 Y=CONST1;\n"); - fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_BUF_))); - fprintf(f, "GATE NOT %d Y=!A; PIN * INV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_NOT_))); + fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_BUF_))); + fprintf(f, "GATE NOT %d Y=!A; PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_NOT_))); if (enabled_gates.count("AND")) - fprintf(f, "GATE AND %d Y=A*B; PIN * NONINV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_AND_))); + fprintf(f, "GATE AND %d Y=A*B; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_AND_))); if (enabled_gates.count("NAND")) - fprintf(f, "GATE NAND %d Y=!(A*B); PIN * INV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_NAND_))); + fprintf(f, "GATE NAND %d Y=!(A*B); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_NAND_))); if (enabled_gates.count("OR")) - fprintf(f, "GATE OR %d Y=A+B; PIN * NONINV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_OR_))); + fprintf(f, "GATE OR %d Y=A+B; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_OR_))); if (enabled_gates.count("NOR")) - fprintf(f, "GATE NOR %d Y=!(A+B); PIN * INV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_NOR_))); + fprintf(f, "GATE NOR %d Y=!(A+B); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_NOR_))); if (enabled_gates.count("XOR")) - fprintf(f, "GATE XOR %d Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_type_cost.at(ID($_XOR_))); + fprintf(f, "GATE XOR %d Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XOR_))); if (enabled_gates.count("XNOR")) - fprintf(f, "GATE XNOR %d Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_type_cost.at(ID($_XNOR_))); + fprintf(f, "GATE XNOR %d Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XNOR_))); if (enabled_gates.count("ANDNOT")) - fprintf(f, "GATE ANDNOT %d Y=A*!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_type_cost.at(ID($_ANDNOT_))); + fprintf(f, "GATE ANDNOT %d Y=A*!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ANDNOT_))); if (enabled_gates.count("ORNOT")) - fprintf(f, "GATE ORNOT %d Y=A+!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_type_cost.at(ID($_ORNOT_))); + fprintf(f, "GATE ORNOT %d Y=A+!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ORNOT_))); if (enabled_gates.count("AOI3")) - fprintf(f, "GATE AOI3 %d Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_AOI3_))); + fprintf(f, "GATE AOI3 %d Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_AOI3_))); if (enabled_gates.count("OAI3")) - fprintf(f, "GATE OAI3 %d Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_OAI3_))); + fprintf(f, "GATE OAI3 %d Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_OAI3_))); if (enabled_gates.count("AOI4")) - fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_AOI4_))); + fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_AOI4_))); if (enabled_gates.count("OAI4")) - fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n", cell_type_cost.at(ID($_OAI4_))); + fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_OAI4_))); if (enabled_gates.count("MUX")) - fprintf(f, "GATE MUX %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_type_cost.at(ID($_MUX_))); + fprintf(f, "GATE MUX %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_MUX_))); if (enabled_gates.count("NMUX")) - fprintf(f, "GATE NMUX %d Y=!((A*B)+(S*B)+(!S*A)); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_type_cost.at(ID($_NMUX_))); + fprintf(f, "GATE NMUX %d Y=!((A*B)+(S*B)+(!S*A)); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_NMUX_))); if (map_mux4) - fprintf(f, "GATE MUX4 %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*cell_type_cost.at(ID($_MUX_))); + fprintf(f, "GATE MUX4 %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*cell_cost.at(ID($_MUX_))); if (map_mux8) - fprintf(f, "GATE MUX8 %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*cell_type_cost.at(ID($_MUX_))); + fprintf(f, "GATE MUX8 %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*cell_cost.at(ID($_MUX_))); if (map_mux16) - fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*cell_type_cost.at(ID($_MUX_))); + fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*cell_cost.at(ID($_MUX_))); fclose(f); if (!lut_costs.empty()) { diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index e72a6f84b81..a13a8413454 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -1025,7 +1025,7 @@ struct TestCellPass : public Pass { num_cells++; } } - CellCosts costs(CellCosts::DEFAULT, design); + CellCosts costs(design); Pass::call(design, "select gold"); for (auto mod : design->selected_modules()) { log_assert(mod->name.str() == "\\gold");