Skip to content

Commit

Permalink
cost: fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Emil Tywoniak authored and Emil Tywoniak committed Apr 17, 2024
1 parent 64df131 commit 2c930d2
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 92 deletions.
176 changes: 89 additions & 87 deletions kernel/cost.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ USING_YOSYS_NAMESPACE

int CellCosts::get(RTLIL::Module *mod)
{
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);

Expand All @@ -22,34 +19,34 @@ static int y_coef(RTLIL::IdString type)
{
// clang-format off
if (// equality
type == ID('$bweqx') ||
type == ID('$nex') ||
type == ID('$eqx') ||
type == ID($bweqx) ||
type == ID($nex) ||
type == ID($eqx) ||
// basic logic
type == ID('$and') ||
type == ID('$or') ||
type == ID('$xor') ||
type == ID('$xnor') ||
type == ID('$not') ||
type == ID($and) ||
type == ID($or) ||
type == ID($xor) ||
type == ID($xnor) ||
type == ID($not) ||
// mux
type == ID('$bwmux') ||
type == ID('$mux') ||
type == ID('$demux') ||
type == ID($bwmux) ||
type == ID($mux) ||
type == ID($demux) ||
// others
type == ID('$tribuf')) {
type == ID($tribuf)) {
return 1;
} else if (type == ID('$neg')) {
} else if (type == ID($neg)) {
return 4;
} else if (type == ID('$fa')) {
} else if (type == ID($fa)) {
return 5;
} else if (// multi-bit adders
type == ID('$add') ||
type == ID('$sub') ||
type == ID('$alu')) {
type == ID($add) ||
type == ID($sub) ||
type == ID($alu)) {
return 8;
} else if (// left shift
type == ID('$shl') ||
type == ID('$sshl')) {
type == ID($shl) ||
type == ID($sshl)) {
return 10;
}
// clang-format on
Expand All @@ -60,31 +57,32 @@ static int max_inp_coef(RTLIL::IdString type)
{
// clang-format off
if (// binop reduce
type == ID('$reduce_and') ||
type == ID('$reduce_or') ||
type == ID('$reduce_xor') ||
type == ID('$reduce_xnor') ||
type == ID('$reduce_bool') ||
type == ID($reduce_and) ||
type == ID($reduce_or) ||
type == ID($reduce_xor) ||
type == ID($reduce_xnor) ||
type == ID($reduce_bool) ||
// others
type == ID('$logic_not') ||
type == ID('$bmux')) {
type == ID($logic_not) ||
type == ID($pmux) ||
type == ID($bmux)) {
return 1;
} else if (// equality
type == ID('$eq') ||
type == ID('$ne') ||
type == ID($eq) ||
type == ID($ne) ||
// logic
type == ID('$logic_and') ||
type == ID('$logic_or')) {
type == ID($logic_and) ||
type == ID($logic_or)) {
return 2;
} else if (type == ID('$lcu')) {
} else if (type == ID($lcu)) {
return 5;
} else if (// comparison
type == ID('$lt') ||
type == ID('$le') ||
type == ID('$ge') ||
type == ID('$gt') ||
type == ID($lt) ||
type == ID($le) ||
type == ID($ge) ||
type == ID($gt) ||
// others
type == ID('$sop')) {
type == ID($sop)) {
return 6;
}
// clang-format on
Expand All @@ -94,101 +92,105 @@ static int sum_coef(RTLIL::IdString type)
{
// clang-format off
if (// right shift
type == ID('$shr') ||
type == ID('$sshr')) {
type == ID($shr) ||
type == ID($sshr)) {
return 4;
} else if (// shift
type == ID('$shift') ||
type == ID('$shiftx')) {
type == ID($shift) ||
type == ID($shiftx)) {
return 8;
}
// clang-format on

// clang-format on
return 0;
}

static bool is_free(RTLIL::IdString type)
{
// clang-format off
return (// tags
type == ID('$overwrite_tag') ||
type == ID('$set_tag') ||
type == ID('$original_tag') ||
type == ID('$get_tag') ||
type == ID($overwrite_tag) ||
type == ID($set_tag) ||
type == ID($original_tag) ||
type == ID($get_tag) ||
// formal
type == ID('$check') ||
type == ID('$equiv') ||
type == ID('$initstate') ||
type == ID('$assert') ||
type == ID('$assume') ||
type == ID('$live') ||
type == ID('$cover') ||
type == ID('$allseq') ||
type == ID('$allconst') ||
type == ID('$anyseq') ||
type == ID('$anyinit') ||
type == ID('$anyconst') ||
type == ID('$fair') ||
type == ID($check) ||
type == ID($equiv) ||
type == ID($initstate) ||
type == ID($assert) ||
type == ID($assume) ||
type == ID($live) ||
type == ID($cover) ||
type == ID($allseq) ||
type == ID($allconst) ||
type == ID($anyseq) ||
type == ID($anyinit) ||
type == ID($anyconst) ||
type == ID($fair) ||
// utilities
type == ID('$scopeinfo') ||
type == ID('$print') ||
type == ID($scopeinfo) ||
type == ID($print) ||
// real but free
type == ID('$concat') ||
type == ID('$slice') ||
type == ID('$pos') ||
type == ID($concat) ||
type == ID($slice) ||
type == ID($pos) ||
// specify
type == ID('$specrule') ||
type == ID('$specify2') ||
type == ID('$specify3'));
type == ID($specrule) ||
type == ID($specify2) ||
type == ID($specify3));
// clang-format on
}

static const RTLIL::IdString port_width_params[] = {
ID::WIDTH, ID::A_WIDTH, ID::B_WIDTH, ID::S_WIDTH, ID::Y_WIDTH,
};

// Ditto but without Y_WIDTH
// No neat solution available: https://stackoverflow.com/questions/3154170/combine-two-constant-strings-or-arrays-into-one-constant-string-or-array-at
static const RTLIL::IdString input_width_params[] = {
ID::WIDTH,
ID::A_WIDTH,
ID::B_WIDTH,
ID::S_WIDTH,
};

int CellCosts::get(RTLIL::Cell *cell)
{

if (gate_type_cost().count(cell->type))
return gate_type_cost().at(cell->type);

if (design_ && design_->module(cell->type) && cell->parameters.empty()) {
log_debug("%s is a module, recurse\n", cell->name.c_str());
return get(design_->module(cell->type));
} else if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
log_assert(cell->hasPort(ID::Q) && "Weird flip flop");
log_debug("%s is ff\n", cell->name.c_str());
return cell->getParam(ID::WIDTH).as_int();
} else if (y_coef(cell->type)) {
// linear with Y_WIDTH
log_assert(cell->hasParam(ID::Y_WIDTH) && "No Y port");
int width = cell->getParam(ID::Y_WIDTH).as_int();
// linear with Y_WIDTH or WIDTH
log_assert((cell->hasParam(ID::Y_WIDTH) || cell->hasParam(ID::WIDTH)) && "Unknown width");
auto param = cell->hasParam(ID::Y_WIDTH) ? ID::Y_WIDTH : ID::WIDTH;
int width = cell->getParam(param).as_int();
log_debug("%s Y*coef %d * %d\n", cell->name.c_str(), width, y_coef(cell->type));
return width * y_coef(cell->type);
} else if (sum_coef(cell->type)) {
// linear with sum of port widths
int sum = 0;
RTLIL::IdString port_width_params[] = {
ID::WIDTH, ID::A_WIDTH, ID::B_WIDTH, ID::S_WIDTH, ID::Y_WIDTH,
};

for (auto param : port_width_params)
if (cell->hasParam(param))
sum += cell->getParam(param).as_int();

log_debug("%s sum*coef %d * %d\n", cell->name.c_str(), sum, sum_coef(cell->type));
return sum * sum_coef(cell->type);
} else if (max_inp_coef(cell->type)) {
// linear with largest input width
int max = 0;
for (auto param : input_width_params)
RTLIL::IdString input_width_params[] = {
ID::WIDTH,
ID::A_WIDTH,
ID::B_WIDTH,
ID::S_WIDTH,
};

for (RTLIL::IdString param : input_width_params)
if (cell->hasParam(param))
max = std::max(max, cell->getParam(param).as_int());

log_debug("%s max*coef %d * %d\n", cell->name.c_str(), max, max_inp_coef(cell->type));
return max;
} else if (is_free(cell->type)) {
log_debug("%s is free\n", cell->name.c_str());
return 0;
}
// TODO: $fsm $mem.*
Expand Down
17 changes: 12 additions & 5 deletions passes/techmap/flatten.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "kernel/yosys.h"
#include "kernel/utils.h"
#include "kernel/sigtools.h"
#include "kernel/cost.h"

#include <stdlib.h>
#include <stdio.h>
Expand Down Expand Up @@ -60,6 +61,8 @@ struct FlattenWorker
bool ignore_wb = false;
bool create_scopeinfo = true;
bool create_scopename = false;
CellCosts costs;
FlattenWorker(RTLIL::Design *design) : costs(CellCosts(CellCosts::DEFAULT, design)) { }
int max_cost = INT_MAX;

template<class T>
Expand Down Expand Up @@ -305,10 +308,14 @@ struct FlattenWorker
continue;
}

if (tpl->has_attribute(ID::cost) && tpl->attributes[ID::cost].as_int() > max_cost) {
log("Keeping %s.%s (module too big).\n", log_id(module), log_id(cell));
used_modules.insert(tpl);
continue;
// Deliberate short circuit
if (max_cost != INT_MAX) {
int cost = costs.get(cell);
if (cost > max_cost) {
log("Keeping %s.%s (module too big: %d > %d).\n", log_id(module), log_id(cell), cost, max_cost);
used_modules.insert(tpl);
continue;
}
}

log_debug("Flattening %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type));
Expand Down Expand Up @@ -358,7 +365,7 @@ struct FlattenPass : public Pass {
log_header(design, "Executing FLATTEN pass (flatten design).\n");
log_push();

FlattenWorker worker;
FlattenWorker worker(design);

size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
Expand Down

0 comments on commit 2c930d2

Please sign in to comment.