Skip to content

Commit

Permalink
cost: start adding width linear costs
Browse files Browse the repository at this point in the history
  • Loading branch information
Emil Tywoniak authored and Emil Tywoniak committed Apr 12, 2024
1 parent 5718700 commit 8cd6e9d
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ $(eval $(call add_include_file,backends/rtlil/rtlil_backend.h))

OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o
OBJS += kernel/binding.o
OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o
OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o
ifeq ($(ENABLE_ZLIB),1)
OBJS += kernel/fstdata.o
endif
Expand Down
112 changes: 111 additions & 1 deletion kernel/cost.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,117 @@

USING_YOSYS_NAMESPACE

CellCosts::CellCosts(CellCosts::CostKind kind, RTLIL::Design *design) : kind(kind), design(design) {
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);

int module_cost = 1;
for (auto c : mod->cells())
module_cost += get(c);

mod_cost_cache_[mod->name] = module_cost;
return module_cost;
}

static int y_coef(RTLIL::IdString type)
{
if (type == ID('$bweqx') ||
type == ID('$nex') ||
type == ID('$eqx') ||
type == ID('$and') ||
type == ID('$or') ||
type == ID('$xor') ||
type == ID('$xnor') ||
type == ID('$not'))
return 1;
else if (
type == ID('$neg')
)
return 3;
return 0;
}

static int sum_coef(RTLIL::IdString type)
{
if (type == ID('$reduce_and') ||
type == ID('$reduce_or') ||
type == ID('$reduce_xor') ||
type == ID('$reduce_xnor') ||
type == ID('$reduce_bool'))
return 1;

return 0;
}

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())
{
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");
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();
return width * y_coef(cell->type);
} else if (sum_coef(cell->type)) {
// linear with sum of port widths
int sum = 0;

if (cell->hasParam(ID::A_WIDTH))
sum += cell->getParam(ID::A_WIDTH).as_int();
if (cell->hasParam(ID::B_WIDTH))
sum += cell->getParam(ID::B_WIDTH).as_int();
if (cell->hasParam(ID::S_WIDTH))
sum += cell->getParam(ID::S_WIDTH).as_int();
if (cell->hasParam(ID::Y_WIDTH))
sum += cell->getParam(ID::Y_WIDTH).as_int();
if (cell->hasParam(ID::WIDTH))
sum += cell->getParam(ID::WIDTH).as_int();


// TODO CTRL_IN $fsm ?
// TODO CTRL_OUT $fsm ?

return sum * sum_coef(cell->type);
} else if (
cell->type == ID('$overwrite_tag') ||
cell->type == ID('$set_tag') ||
cell->type == ID('$original_tag') ||
cell->type == ID('$get_tag') ||
cell->type == ID('$check') ||
cell->type == ID('$equiv') ||
cell->type == ID('$initstate') ||
cell->type == ID('$assert') ||
cell->type == ID('$assume') ||
cell->type == ID('$live') ||
cell->type == ID('$cover') ||
cell->type == ID('$allseq') ||
cell->type == ID('$allconst') ||
cell->type == ID('$anyseq') ||
cell->type == ID('$anyinit') ||
cell->type == ID('$anyconst') ||
cell->type == ID('$fair') ||
cell->type == ID('$scopeinfo') ||
cell->type == ID('$print') ||
cell->type == ID('$concat') ||
cell->type == ID('$slice') ||
cell->type == ID('$pos')
) {
return 0;
}

log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(cell->type), GetSize(cell->parameters));
return 1;
}


45 changes: 7 additions & 38 deletions kernel/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@ struct CellCosts
};

private:
dict<RTLIL::IdString, int> mod_cost_cache;
CostKind kind;
Design *design = nullptr;
bool type_only;
dict<RTLIL::IdString, int> mod_cost_cache_;
CostKind kind_;
Design *design_ = nullptr;

public:
CellCosts(CostKind kind, Design *design);
CellCosts(CellCosts::CostKind kind, RTLIL::Design *design) : kind_(kind), design_(design) { }

const dict<RTLIL::IdString, int>& gate_type_cost() {
static const dict<RTLIL::IdString, int> default_gate_db = {
Expand Down Expand Up @@ -83,7 +82,7 @@ struct CellCosts
{ ID($_DFF_P_), 16 },
{ ID($_DFF_N_), 16 },
};
switch (kind) {
switch (kind_) {
case DEFAULT:
return default_gate_db;
case CMOS:
Expand All @@ -93,38 +92,8 @@ struct CellCosts
}
}

int 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);

int module_cost = 1;
for (auto c : mod->cells())
module_cost += get(c);

mod_cost_cache[mod->name] = module_cost;
return module_cost;
}

int 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())
{
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");
return cell->getParam(ID::WIDTH).as_int();
}

log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(cell->type), GetSize(cell->parameters));
return 1;
}
int get(RTLIL::Module *mod);
int get(RTLIL::Cell *cell);
};

YOSYS_NAMESPACE_END
Expand Down

0 comments on commit 8cd6e9d

Please sign in to comment.