mirror of
https://github.com/YosysHQ/yosys
synced 2025-07-01 18:38:48 +00:00
hierarchy: morphCell
This commit is contained in:
parent
6922a68cea
commit
d3d5738238
3 changed files with 37 additions and 20 deletions
|
@ -2473,7 +2473,9 @@ RTLIL::Cell *RTLIL::Module::morphCell(RTLIL::IdString type, RTLIL::Cell *old)
|
||||||
// old->type = type;
|
// old->type = type;
|
||||||
// return old;
|
// return old;
|
||||||
// }
|
// }
|
||||||
// TODO xtrace
|
if (old->type == type)
|
||||||
|
return old;
|
||||||
|
|
||||||
if (yosys_xtrace) {
|
if (yosys_xtrace) {
|
||||||
log("#X# Morphing %s.%s from type %s to %s\n", log_id(this), log_id(old), log_id(old->type), log_id(type));
|
log("#X# Morphing %s.%s from type %s to %s\n", log_id(this), log_id(old), log_id(old->type), log_id(type));
|
||||||
log_backtrace("-X- ", yosys_xtrace-1);
|
log_backtrace("-X- ", yosys_xtrace-1);
|
||||||
|
@ -2487,7 +2489,7 @@ RTLIL::Cell *RTLIL::Module::morphCell(RTLIL::IdString type, RTLIL::Cell *old)
|
||||||
new_cell->name = old->name;
|
new_cell->name = old->name;
|
||||||
log_assert(refcount_cells_ == 0);
|
log_assert(refcount_cells_ == 0);
|
||||||
cells_[new_cell->name] = new_cell;
|
cells_[new_cell->name] = new_cell;
|
||||||
delete old;
|
remove(old);
|
||||||
return new_cell;
|
return new_cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1794,7 +1794,10 @@ public:
|
||||||
parent->legacy->parameters.erase(paramname);
|
parent->legacy->parameters.erase(paramname);
|
||||||
}
|
}
|
||||||
// The need for this function implies setPort will be used on incompat types
|
// The need for this function implies setPort will be used on incompat types
|
||||||
void clear() const {}
|
void clear() const {
|
||||||
|
if (parent->is_legacy())
|
||||||
|
parent->legacy->parameters.clear();
|
||||||
|
}
|
||||||
// AAA
|
// AAA
|
||||||
class iterator {
|
class iterator {
|
||||||
typedef std::bidirectional_iterator_tag iterator_category;
|
typedef std::bidirectional_iterator_tag iterator_category;
|
||||||
|
@ -2056,9 +2059,16 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The need for this function implies setPort will be used on incompat types
|
// The need for this function implies setPort will be used on incompat types
|
||||||
void erase(const RTLIL::IdString& portname) { (void)portname; }
|
void erase(const RTLIL::IdString &portname) const
|
||||||
|
{
|
||||||
|
if (parent->is_legacy())
|
||||||
|
parent->legacy->connections_.erase(portname);
|
||||||
|
}
|
||||||
// The need for this function implies setPort will be used on incompat types
|
// The need for this function implies setPort will be used on incompat types
|
||||||
void clear() const {}
|
void clear() const {
|
||||||
|
if (parent->is_legacy())
|
||||||
|
parent->legacy->connections_.clear();
|
||||||
|
}
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return !size();
|
return !size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,17 +327,18 @@ struct IFExpander
|
||||||
// something. or null otherwise (the module should be blackbox or we couldn't
|
// something. or null otherwise (the module should be blackbox or we couldn't
|
||||||
// find it and check is not set).
|
// find it and check is not set).
|
||||||
RTLIL::Module *get_module(RTLIL::Design &design,
|
RTLIL::Module *get_module(RTLIL::Design &design,
|
||||||
RTLIL::Cell &cell,
|
RTLIL::Cell *&cell,
|
||||||
RTLIL::Module &parent,
|
RTLIL::Module &parent,
|
||||||
bool check,
|
bool check,
|
||||||
const std::vector<std::string> &libdirs)
|
const std::vector<std::string> &libdirs)
|
||||||
{
|
{
|
||||||
std::string cell_type = cell.type.str();
|
std::string cell_type = cell->type.str();
|
||||||
RTLIL::Module *abs_mod = design.module("$abstract" + cell_type);
|
RTLIL::Module *abs_mod = design.module("$abstract" + cell_type);
|
||||||
if (abs_mod) {
|
if (abs_mod) {
|
||||||
cell.type = abs_mod->derive(&design, cell_to_mod_params(cell.parameters));
|
auto new_cell_type = abs_mod->derive(&design, cell_to_mod_params(cell->parameters));
|
||||||
cell.parameters.clear();
|
cell->parameters.clear();
|
||||||
RTLIL::Module *mod = design.module(cell.type);
|
cell = cell->module->morphCell(new_cell_type, cell);
|
||||||
|
RTLIL::Module *mod = design.module(cell->type);
|
||||||
log_assert(mod);
|
log_assert(mod);
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
@ -356,12 +357,12 @@ RTLIL::Module *get_module(RTLIL::Design &design,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto &ext : extensions_list) {
|
for (auto &ext : extensions_list) {
|
||||||
std::string filename = dir + "/" + RTLIL::unescape_id(cell.type) + ext.first;
|
std::string filename = dir + "/" + RTLIL::unescape_id(cell->type) + ext.first;
|
||||||
if (!check_file_exists(filename))
|
if (!check_file_exists(filename))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Frontend::frontend_call(&design, NULL, filename, ext.second);
|
Frontend::frontend_call(&design, NULL, filename, ext.second);
|
||||||
RTLIL::Module *mod = design.module(cell.type);
|
RTLIL::Module *mod = design.module(cell->type);
|
||||||
if (!mod)
|
if (!mod)
|
||||||
log_error("File `%s' from libdir does not declare module `%s'.\n",
|
log_error("File `%s' from libdir does not declare module `%s'.\n",
|
||||||
filename.c_str(), cell_type.c_str());
|
filename.c_str(), cell_type.c_str());
|
||||||
|
@ -372,7 +373,7 @@ RTLIL::Module *get_module(RTLIL::Design &design,
|
||||||
// We couldn't find the module anywhere. Complain if check is set.
|
// We couldn't find the module anywhere. Complain if check is set.
|
||||||
if (check)
|
if (check)
|
||||||
log_error("Module `%s' referenced in module `%s' in cell `%s' is not part of the design.\n",
|
log_error("Module `%s' referenced in module `%s' in cell `%s' is not part of the design.\n",
|
||||||
cell_type.c_str(), parent.name.c_str(), cell.name.c_str());
|
cell_type.c_str(), parent.name.c_str(), cell->name.c_str());
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -479,7 +480,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||||
RTLIL::Module *mod = design->module(cell->type);
|
RTLIL::Module *mod = design->module(cell->type);
|
||||||
if (!mod)
|
if (!mod)
|
||||||
{
|
{
|
||||||
mod = get_module(*design, *cell, *module, flag_check || flag_simcheck || flag_smtcheck, libdirs);
|
mod = get_module(*design, cell, *module, flag_check || flag_simcheck || flag_smtcheck, libdirs);
|
||||||
|
|
||||||
// If we still don't have a module, treat the cell as a black box and skip
|
// If we still don't have a module, treat the cell as a black box and skip
|
||||||
// it. Otherwise, we either loaded or derived something so should set the
|
// it. Otherwise, we either loaded or derived something so should set the
|
||||||
|
@ -528,12 +529,16 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell->type = mod->derive(design,
|
{
|
||||||
cell_to_mod_params(cell->parameters),
|
auto params = cell_to_mod_params(cell->parameters);
|
||||||
|
cell->parameters.clear();
|
||||||
|
auto type = mod->derive(design,
|
||||||
|
params,
|
||||||
if_expander.interfaces_to_add_to_submodule,
|
if_expander.interfaces_to_add_to_submodule,
|
||||||
if_expander.modports_used_in_submodule);
|
if_expander.modports_used_in_submodule);
|
||||||
cell->parameters.clear();
|
cell = mod->morphCell(type, cell);
|
||||||
did_something = true;
|
did_something = true;
|
||||||
|
}
|
||||||
|
|
||||||
handle_interface_instance:
|
handle_interface_instance:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue