Skip to content

Commit

Permalink
cost: separate from previous functionality, decrease diff at users
Browse files Browse the repository at this point in the history
  • Loading branch information
widlarizer committed May 7, 2024
1 parent 4ea3112 commit 16c735e
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 48 deletions.
2 changes: 1 addition & 1 deletion kernel/cost.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
30 changes: 12 additions & 18 deletions kernel/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,17 @@ YOSYS_NAMESPACE_BEGIN
struct CellCosts
{

enum CostKind {
DEFAULT,
CMOS,
};

private:
dict<RTLIL::IdString, int> 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<RTLIL::IdString, int>& gate_type_cost() {
static const dict<RTLIL::IdString, int> default_gate_db = {
static const dict<RTLIL::IdString, int>& default_gate_cost() {
// Default size heuristics for several common PDK standard cells
// used by abc and stat
static const dict<RTLIL::IdString, int> db = {
{ ID($_BUF_), 1 },
{ ID($_NOT_), 2 },
{ ID($_AND_), 4 },
Expand All @@ -59,8 +55,13 @@ struct CellCosts
{ ID($_MUX_), 4 },
{ ID($_NMUX_), 4 },
};
return db;
}

static const dict<RTLIL::IdString, int> cmos_transistors_db = {
static const dict<RTLIL::IdString, int>& cmos_gate_cost() {
// Estimated CMOS transistor counts for several common PDK standard cells
// used by stat and optionally by abc
static const dict<RTLIL::IdString, int> db = {
{ ID($_BUF_), 1 },
{ ID($_NOT_), 2 },
{ ID($_AND_), 6 },
Expand All @@ -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);
Expand Down
8 changes: 3 additions & 5 deletions passes/cmds/stat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion passes/hierarchy/keep_hierarchy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
42 changes: 20 additions & 22 deletions passes/techmap/abc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1047,52 +1047,50 @@ 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");
if (f == nullptr)
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()) {
Expand Down
2 changes: 1 addition & 1 deletion passes/tests/test_cell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit 16c735e

Please sign in to comment.