3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-04 06:26:09 +00:00

Merge pull request #5512 from YosysHQ/emil/turbo-celltypes

celltypes: compile-time lookup tables for internal cells
This commit is contained in:
Emil J 2026-03-04 14:47:57 +00:00 committed by GitHub
commit 0d7a875675
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 945 additions and 355 deletions

View file

@ -20,7 +20,7 @@
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/celledges.h"
#include "kernel/celltypes.h"
#include "kernel/newcelltypes.h"
#include "kernel/utils.h"
#include "kernel/log_help.h"

View file

@ -1,5 +1,6 @@
#include "kernel/yosys.h"
#include "kernel/celltypes.h"
#include "kernel/newcelltypes.h"
#include "kernel/ff.h"
USING_YOSYS_NAMESPACE
@ -123,7 +124,7 @@ struct LibertyStubber {
return;
}
if (RTLIL::builtin_ff_cell_types().count(base_name))
if (StaticCellTypes::categories.is_ff(base_name))
return liberty_flop(base, derived, f);
auto& base_type = ct.cell_types[base_name];

View file

@ -18,7 +18,7 @@
*/
#include "kernel/yosys.h"
#include "kernel/celltypes.h"
#include "kernel/newcelltypes.h"
#include "kernel/sigtools.h"
#include "kernel/log_help.h"
@ -488,7 +488,7 @@ static int parse_comma_list(std::set<RTLIL::IdString> &tokens, const std::string
}
}
static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::vector<expand_rule_t> &rules, std::set<RTLIL::IdString> &limits, int max_objects, char mode, CellTypes &ct, bool eval_only)
static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::vector<expand_rule_t> &rules, std::set<RTLIL::IdString> &limits, int max_objects, char mode, NewCellTypes &ct, bool eval_only)
{
int sel_objects = 0;
bool is_input, is_output;
@ -564,7 +564,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char
std::vector<expand_rule_t> rules;
std::set<RTLIL::IdString> limits;
CellTypes ct;
NewCellTypes ct;
if (mode != 'x')
ct.setup(design);

View file

@ -18,7 +18,7 @@
*/
#include "kernel/yosys.h"
#include "kernel/celltypes.h"
#include "kernel/newcelltypes.h"
#include "kernel/sigtools.h"
#include "kernel/utils.h"
#include "kernel/log_help.h"

View file

@ -5,6 +5,7 @@
#include "kernel/yosys_common.h"
#include "kernel/sigtools.h"
#include "kernel/satgen.h"
#include "kernel/newcelltypes.h"
YOSYS_NAMESPACE_BEGIN

View file

@ -21,6 +21,7 @@
#include "kernel/sigtools.h"
#include "kernel/log.h"
#include "kernel/celltypes.h"
#include "kernel/newcelltypes.h"
#include "kernel/ffinit.h"
#include <stdlib.h>
#include <stdio.h>
@ -101,7 +102,10 @@ struct keep_cache_t
};
keep_cache_t keep_cache;
CellTypes ct_reg, ct_all;
static constexpr auto ct_reg = StaticCellTypes::Categories::join(
StaticCellTypes::Compat::mem_ff,
StaticCellTypes::categories.is_anyinit);
NewCellTypes ct_all;
int count_rm_cells, count_rm_wires;
void rmunused_module_cells(Module *module, bool verbose)
@ -310,10 +314,10 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
if (!purge_mode)
for (auto &it : module->cells_) {
RTLIL::Cell *cell = it.second;
if (ct_reg.cell_known(cell->type)) {
if (ct_reg(cell->type)) {
bool clk2fflogic = cell->get_bool_attribute(ID(clk2fflogic));
for (auto &it2 : cell->connections())
if (clk2fflogic ? it2.first == ID::D : ct_reg.cell_output(cell->type, it2.first))
if (clk2fflogic ? it2.first == ID::D : ct_all.cell_output(cell->type, it2.first))
register_signals.add(it2.second);
}
for (auto &it2 : cell->connections())
@ -517,14 +521,12 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
bool rmunused_module_init(RTLIL::Module *module, bool verbose)
{
bool did_something = false;
CellTypes fftypes;
fftypes.setup_internals_mem();
SigMap sigmap(module);
dict<SigBit, State> qbits;
for (auto cell : module->cells())
if (fftypes.cell_known(cell->type) && cell->hasPort(ID::Q))
if (StaticCellTypes::Compat::internals_mem_ff(cell->type) && cell->hasPort(ID::Q))
{
SigSpec sig = cell->getPort(ID::Q);
@ -697,10 +699,6 @@ struct OptCleanPass : public Pass {
keep_cache.reset(design, purge_mode);
ct_reg.setup_internals_mem();
ct_reg.setup_internals_anyinit();
ct_reg.setup_stdcells_mem();
ct_all.setup(design);
count_rm_cells = 0;
@ -719,7 +717,6 @@ struct OptCleanPass : public Pass {
design->check();
keep_cache.reset();
ct_reg.clear();
ct_all.clear();
log_pop();
@ -760,10 +757,6 @@ struct CleanPass : public Pass {
keep_cache.reset(design);
ct_reg.setup_internals_mem();
ct_reg.setup_internals_anyinit();
ct_reg.setup_stdcells_mem();
ct_all.setup(design);
count_rm_cells = 0;
@ -783,7 +776,6 @@ struct CleanPass : public Pass {
design->check();
keep_cache.reset();
ct_reg.clear();
ct_all.clear();
request_garbage_collection();

View file

@ -20,6 +20,7 @@
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/celltypes.h"
#include "kernel/newcelltypes.h"
#include "kernel/utils.h"
#include "kernel/log.h"
#include <stdlib.h>
@ -31,7 +32,7 @@ PRIVATE_NAMESPACE_BEGIN
bool did_something;
void replace_undriven(RTLIL::Module *module, const CellTypes &ct)
void replace_undriven(RTLIL::Module *module, const NewCellTypes &ct)
{
SigMap sigmap(module);
SigPool driven_signals;
@ -407,9 +408,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
}
}
CellTypes ct_memcells;
ct_memcells.setup_stdcells_mem();
if (!noclkinv)
for (auto cell : module->cells())
if (design->selected(module, cell)) {
@ -433,7 +431,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($dffe), ID($adffe), ID($aldffe), ID($sdffe), ID($sdffce), ID($dffsre), ID($dlatch), ID($adlatch), ID($dlatchsr)))
handle_polarity_inv(cell, ID::EN, ID::EN_POLARITY, assign_map, invert_map);
if (!ct_memcells.cell_known(cell->type))
if (!StaticCellTypes::Compat::stdcells_mem(cell->type))
continue;
handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", ID::S, assign_map, invert_map);
@ -2294,7 +2292,7 @@ struct OptExprPass : public Pass {
}
extra_args(args, argidx, design);
CellTypes ct(design);
NewCellTypes ct(design);
for (auto module : design->selected_modules())
{
log("Optimizing module %s.\n", log_id(module));

View file

@ -23,6 +23,7 @@
#include "kernel/modtools.h"
#include "kernel/utils.h"
#include "kernel/macc.h"
#include "kernel/newcelltypes.h"
#include <iterator>
USING_YOSYS_NAMESPACE
@ -38,19 +39,18 @@ struct ShareWorkerConfig
bool opt_force;
bool opt_aggressive;
bool opt_fast;
pool<RTLIL::IdString> generic_uni_ops, generic_bin_ops, generic_cbin_ops, generic_other_ops;
StaticCellTypes::Categories::Category generic_uni_ops, generic_bin_ops, generic_cbin_ops, generic_other_ops;
};
struct ShareWorker
{
const ShareWorkerConfig config;
int limit;
pool<RTLIL::IdString> generic_ops;
StaticCellTypes::Categories::Category generic_ops;
RTLIL::Design *design;
RTLIL::Module *module;
CellTypes fwd_ct, cone_ct;
ModWalker modwalker;
pool<RTLIL::Cell*> cells_to_remove;
@ -75,7 +75,7 @@ struct ShareWorker
queue_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end());
for (auto &it : module->cells_)
if (!fwd_ct.cell_known(it.second->type)) {
if (!StaticCellTypes::Compat::internals_nomem_noff(it.second->type)) {
pool<RTLIL::SigBit> &bits = modwalker.cell_inputs[it.second];
queue_bits.insert(bits.begin(), bits.end());
}
@ -95,7 +95,7 @@ struct ShareWorker
queue_bits.insert(bits.begin(), bits.end());
visited_cells.insert(pbit.cell);
}
if (fwd_ct.cell_known(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) {
if (StaticCellTypes::Compat::internals_nomem_noff(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) {
pool<RTLIL::SigBit> &bits = modwalker.cell_inputs[pbit.cell];
terminal_bits.insert(bits.begin(), bits.end());
queue_bits.insert(bits.begin(), bits.end());
@ -388,7 +388,7 @@ struct ShareWorker
continue;
}
if (generic_ops.count(cell->type)) {
if (generic_ops(cell->type)) {
if (config.opt_aggressive)
shareable_cells.insert(cell);
continue;
@ -412,7 +412,7 @@ struct ShareWorker
return true;
}
if (config.generic_uni_ops.count(c1->type))
if (config.generic_uni_ops(c1->type))
{
if (!config.opt_aggressive)
{
@ -429,7 +429,7 @@ struct ShareWorker
return true;
}
if (config.generic_bin_ops.count(c1->type) || c1->type == ID($alu))
if (config.generic_bin_ops(c1->type) || c1->type == ID($alu))
{
if (!config.opt_aggressive)
{
@ -449,7 +449,7 @@ struct ShareWorker
return true;
}
if (config.generic_cbin_ops.count(c1->type))
if (config.generic_cbin_ops(c1->type))
{
if (!config.opt_aggressive)
{
@ -511,7 +511,7 @@ struct ShareWorker
{
log_assert(c1->type == c2->type);
if (config.generic_uni_ops.count(c1->type))
if (config.generic_uni_ops(c1->type))
{
if (c1->parameters.at(ID::A_SIGNED).as_bool() != c2->parameters.at(ID::A_SIGNED).as_bool())
{
@ -560,11 +560,11 @@ struct ShareWorker
return supercell;
}
if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type) || c1->type == ID($alu))
if (config.generic_bin_ops(c1->type) || config.generic_cbin_ops(c1->type) || c1->type == ID($alu))
{
bool modified_src_cells = false;
if (config.generic_cbin_ops.count(c1->type))
if (config.generic_cbin_ops(c1->type))
{
int score_unflipped = max(c1->parameters.at(ID::A_WIDTH).as_int(), c2->parameters.at(ID::A_WIDTH).as_int()) +
max(c1->parameters.at(ID::B_WIDTH).as_int(), c2->parameters.at(ID::B_WIDTH).as_int());
@ -758,7 +758,7 @@ struct ShareWorker
recursion_state.insert(cell);
for (auto c : consumer_cells)
if (fwd_ct.cell_known(c->type)) {
if (StaticCellTypes::Compat::internals_nomem_noff(c->type)) {
const pool<RTLIL::SigBit> &bits = find_forbidden_controls(c);
forbidden_controls_cache[cell].insert(bits.begin(), bits.end());
}
@ -897,7 +897,7 @@ struct ShareWorker
return activation_patterns_cache.at(cell);
}
for (auto &pbit : modwalker.signal_consumers[bit]) {
log_assert(fwd_ct.cell_known(pbit.cell->type));
log_assert(StaticCellTypes::Compat::internals_nomem_noff(pbit.cell->type));
if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID::A || pbit.port == ID::B))
driven_data_muxes.insert(pbit.cell);
else
@ -1214,24 +1214,10 @@ struct ShareWorker
ShareWorker(ShareWorkerConfig config, RTLIL::Design* design) :
config(config), design(design), modwalker(design)
{
generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end());
generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end());
generic_ops.insert(config.generic_cbin_ops.begin(), config.generic_cbin_ops.end());
generic_ops.insert(config.generic_other_ops.begin(), config.generic_other_ops.end());
fwd_ct.setup_internals();
cone_ct.setup_internals();
cone_ct.cell_types.erase(ID($mul));
cone_ct.cell_types.erase(ID($mod));
cone_ct.cell_types.erase(ID($div));
cone_ct.cell_types.erase(ID($modfloor));
cone_ct.cell_types.erase(ID($divfloor));
cone_ct.cell_types.erase(ID($pow));
cone_ct.cell_types.erase(ID($shl));
cone_ct.cell_types.erase(ID($shr));
cone_ct.cell_types.erase(ID($sshl));
cone_ct.cell_types.erase(ID($sshr));
generic_ops = StaticCellTypes::Categories::join(generic_ops, config.generic_uni_ops);
generic_ops = StaticCellTypes::Categories::join(generic_ops, config.generic_bin_ops);
generic_ops = StaticCellTypes::Categories::join(generic_ops, config.generic_cbin_ops);
generic_ops = StaticCellTypes::Categories::join(generic_ops, config.generic_other_ops);
}
void operator()(RTLIL::Module *module) {
@ -1561,45 +1547,45 @@ struct SharePass : public Pass {
config.opt_aggressive = false;
config.opt_fast = false;
config.generic_uni_ops.insert(ID($not));
// config.generic_uni_ops.insert(ID($pos));
config.generic_uni_ops.insert(ID($neg));
config.generic_uni_ops.set_id(ID($not));
// config.generic_uni_ops.set_id(ID($pos));
config.generic_uni_ops.set_id(ID($neg));
config.generic_cbin_ops.insert(ID($and));
config.generic_cbin_ops.insert(ID($or));
config.generic_cbin_ops.insert(ID($xor));
config.generic_cbin_ops.insert(ID($xnor));
config.generic_cbin_ops.set_id(ID($and));
config.generic_cbin_ops.set_id(ID($or));
config.generic_cbin_ops.set_id(ID($xor));
config.generic_cbin_ops.set_id(ID($xnor));
config.generic_bin_ops.insert(ID($shl));
config.generic_bin_ops.insert(ID($shr));
config.generic_bin_ops.insert(ID($sshl));
config.generic_bin_ops.insert(ID($sshr));
config.generic_bin_ops.set_id(ID($shl));
config.generic_bin_ops.set_id(ID($shr));
config.generic_bin_ops.set_id(ID($sshl));
config.generic_bin_ops.set_id(ID($sshr));
config.generic_bin_ops.insert(ID($lt));
config.generic_bin_ops.insert(ID($le));
config.generic_bin_ops.insert(ID($eq));
config.generic_bin_ops.insert(ID($ne));
config.generic_bin_ops.insert(ID($eqx));
config.generic_bin_ops.insert(ID($nex));
config.generic_bin_ops.insert(ID($ge));
config.generic_bin_ops.insert(ID($gt));
config.generic_bin_ops.set_id(ID($lt));
config.generic_bin_ops.set_id(ID($le));
config.generic_bin_ops.set_id(ID($eq));
config.generic_bin_ops.set_id(ID($ne));
config.generic_bin_ops.set_id(ID($eqx));
config.generic_bin_ops.set_id(ID($nex));
config.generic_bin_ops.set_id(ID($ge));
config.generic_bin_ops.set_id(ID($gt));
config.generic_cbin_ops.insert(ID($add));
config.generic_cbin_ops.insert(ID($mul));
config.generic_cbin_ops.set_id(ID($add));
config.generic_cbin_ops.set_id(ID($mul));
config.generic_bin_ops.insert(ID($sub));
config.generic_bin_ops.insert(ID($div));
config.generic_bin_ops.insert(ID($mod));
config.generic_bin_ops.insert(ID($divfloor));
config.generic_bin_ops.insert(ID($modfloor));
// config.generic_bin_ops.insert(ID($pow));
config.generic_bin_ops.set_id(ID($sub));
config.generic_bin_ops.set_id(ID($div));
config.generic_bin_ops.set_id(ID($mod));
config.generic_bin_ops.set_id(ID($divfloor));
config.generic_bin_ops.set_id(ID($modfloor));
// config.generic_bin_ops.set_id(ID($pow));
config.generic_uni_ops.insert(ID($logic_not));
config.generic_cbin_ops.insert(ID($logic_and));
config.generic_cbin_ops.insert(ID($logic_or));
config.generic_uni_ops.set_id(ID($logic_not));
config.generic_cbin_ops.set_id(ID($logic_and));
config.generic_cbin_ops.set_id(ID($logic_or));
config.generic_other_ops.insert(ID($alu));
config.generic_other_ops.insert(ID($macc));
config.generic_other_ops.set_id(ID($alu));
config.generic_other_ops.set_id(ID($macc));
log_header(design, "Executing SHARE pass (SAT-based resource sharing).\n");

View file

@ -20,6 +20,7 @@
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/celltypes.h"
#include "kernel/newcelltypes.h"
#include "kernel/mem.h"
#include "kernel/fstdata.h"
#include "kernel/ff.h"

View file

@ -43,7 +43,7 @@
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/celltypes.h"
#include "kernel/newcelltypes.h"
#include "kernel/ffinit.h"
#include "kernel/ff.h"
#include "kernel/cost.h"
@ -2455,7 +2455,7 @@ struct AbcPass : public Pass {
continue;
}
CellTypes ct(design);
NewCellTypes ct(design);
std::vector<RTLIL::Cell*> all_cells = mod->selected_cells();
pool<RTLIL::Cell*> unassigned_cells(all_cells.begin(), all_cells.end());

View file

@ -21,7 +21,7 @@
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/utils.h"
#include "kernel/celltypes.h"
#include "kernel/newcelltypes.h"
#include "kernel/timinginfo.h"
#include <optional>