mirror of https://github.com/YosysHQ/yosys.git
Split out logic for reprocessing an AstModule
This will enable other features to use same core logic for replacing an existing AstModule with a newly elaborated version.
This commit is contained in:
parent
ee230f2bb9
commit
bd16d01c0e
|
@ -983,8 +983,7 @@ static bool param_has_no_default(const AstNode *param) {
|
||||||
(children.size() == 1 && children[0]->type == AST_RANGE);
|
(children.size() == 1 && children[0]->type == AST_RANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create and add a new AstModule from an AST_MODULE AST node
|
static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false)
|
||||||
static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false)
|
|
||||||
{
|
{
|
||||||
log_assert(current_scope.empty());
|
log_assert(current_scope.empty());
|
||||||
log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE);
|
log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE);
|
||||||
|
@ -1197,6 +1196,42 @@ static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstN
|
||||||
}
|
}
|
||||||
|
|
||||||
design->add(current_module);
|
design->add(current_module);
|
||||||
|
return current_module;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::Module *
|
||||||
|
AST_INTERNAL::process_and_replace_module(RTLIL::Design *design,
|
||||||
|
RTLIL::Module *old_module,
|
||||||
|
AstNode *new_ast,
|
||||||
|
AstNode *original_ast)
|
||||||
|
{
|
||||||
|
// The old module will be deleted. Rename and mark for deletion, using
|
||||||
|
// a static counter to make sure we get a unique name.
|
||||||
|
static unsigned counter;
|
||||||
|
std::ostringstream new_name;
|
||||||
|
new_name << old_module->name.str()
|
||||||
|
<< "_before_process_and_replace_module_"
|
||||||
|
<< counter;
|
||||||
|
++counter;
|
||||||
|
|
||||||
|
design->rename(old_module, new_name.str());
|
||||||
|
old_module->set_bool_attribute(ID::to_delete);
|
||||||
|
|
||||||
|
// Check if the module was the top module. If it was, we need to remove
|
||||||
|
// the top attribute and put it on the new module.
|
||||||
|
bool is_top = false;
|
||||||
|
if (old_module->get_bool_attribute(ID::initial_top)) {
|
||||||
|
old_module->attributes.erase(ID::initial_top);
|
||||||
|
is_top = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate RTLIL from AST for the new module and add to the design:
|
||||||
|
RTLIL::Module* new_module = process_module(design, new_ast, false, original_ast);
|
||||||
|
|
||||||
|
if (is_top)
|
||||||
|
new_module->set_bool_attribute(ID::top);
|
||||||
|
|
||||||
|
return new_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
// renames identifiers in tasks and functions within a package
|
// renames identifiers in tasks and functions within a package
|
||||||
|
@ -1412,11 +1447,10 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule
|
||||||
|
|
||||||
// When an interface instance is found in a module, the whole RTLIL for the module will be rederived again
|
// When an interface instance is found in a module, the whole RTLIL for the module will be rederived again
|
||||||
// from AST. The interface members are copied into the AST module with the prefix of the interface.
|
// from AST. The interface members are copied into the AST module with the prefix of the interface.
|
||||||
void AstModule::reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module*> &local_interfaces)
|
void AstModule::expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module*> &local_interfaces)
|
||||||
{
|
{
|
||||||
loadconfig();
|
loadconfig();
|
||||||
|
|
||||||
bool is_top = false;
|
|
||||||
AstNode *new_ast = ast->clone();
|
AstNode *new_ast = ast->clone();
|
||||||
for (auto &intf : local_interfaces) {
|
for (auto &intf : local_interfaces) {
|
||||||
std::string intfname = intf.first.str();
|
std::string intfname = intf.first.str();
|
||||||
|
@ -1473,28 +1507,15 @@ void AstModule::reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdStri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The old module will be deleted. Rename and mark for deletion:
|
// Generate RTLIL from AST for the new module and add to the design,
|
||||||
std::string original_name = this->name.str();
|
// renaming this module to move it out of the way.
|
||||||
std::string changed_name = original_name + "_before_replacing_local_interfaces";
|
RTLIL::Module* new_module =
|
||||||
design->rename(this, changed_name);
|
process_and_replace_module(design, this, new_ast, ast_before_replacing_interface_ports);
|
||||||
this->set_bool_attribute(ID::to_delete);
|
|
||||||
|
|
||||||
// Check if the module was the top module. If it was, we need to remove the top attribute and put it on the
|
delete new_ast;
|
||||||
// new module.
|
|
||||||
if (this->get_bool_attribute(ID::initial_top)) {
|
|
||||||
this->attributes.erase(ID::initial_top);
|
|
||||||
is_top = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate RTLIL from AST for the new module and add to the design:
|
|
||||||
process_module(design, new_ast, false, ast_before_replacing_interface_ports);
|
|
||||||
delete(new_ast);
|
|
||||||
RTLIL::Module* mod = design->module(original_name);
|
|
||||||
if (is_top)
|
|
||||||
mod->set_bool_attribute(ID::top);
|
|
||||||
|
|
||||||
// Set the attribute "interfaces_replaced_in_module" so that it does not happen again.
|
// Set the attribute "interfaces_replaced_in_module" so that it does not happen again.
|
||||||
mod->set_bool_attribute(ID::interfaces_replaced_in_module);
|
new_module->set_bool_attribute(ID::interfaces_replaced_in_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces
|
// create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces
|
||||||
|
|
|
@ -348,7 +348,7 @@ namespace AST
|
||||||
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) override;
|
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) override;
|
||||||
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override;
|
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override;
|
||||||
std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, AstNode **new_ast_out, bool quiet = false);
|
std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, AstNode **new_ast_out, bool quiet = false);
|
||||||
void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override;
|
void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override;
|
||||||
RTLIL::Module *clone() const override;
|
RTLIL::Module *clone() const override;
|
||||||
void loadconfig() const;
|
void loadconfig() const;
|
||||||
};
|
};
|
||||||
|
@ -395,6 +395,18 @@ namespace AST_INTERNAL
|
||||||
extern dict<std::string, pool<int>> current_memwr_visible;
|
extern dict<std::string, pool<int>> current_memwr_visible;
|
||||||
struct LookaheadRewriter;
|
struct LookaheadRewriter;
|
||||||
struct ProcessGenerator;
|
struct ProcessGenerator;
|
||||||
|
|
||||||
|
// Create and add a new AstModule from new_ast, then use it to replace
|
||||||
|
// old_module in design, renaming old_module to move it out of the way.
|
||||||
|
// Return the new module.
|
||||||
|
//
|
||||||
|
// If original_ast is not null, it will be used as the AST node for the
|
||||||
|
// new module. Otherwise, new_ast will be used.
|
||||||
|
RTLIL::Module *
|
||||||
|
process_and_replace_module(RTLIL::Design *design,
|
||||||
|
RTLIL::Module *old_module,
|
||||||
|
AST::AstNode *new_ast,
|
||||||
|
AST::AstNode *original_ast = nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
YOSYS_NAMESPACE_END
|
YOSYS_NAMESPACE_END
|
||||||
|
|
|
@ -936,9 +936,9 @@ void RTLIL::Module::makeblackbox()
|
||||||
set_bool_attribute(ID::blackbox);
|
set_bool_attribute(ID::blackbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTLIL::Module::reprocess_module(RTLIL::Design *, const dict<RTLIL::IdString, RTLIL::Module *> &)
|
void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict<RTLIL::IdString, RTLIL::Module *> &)
|
||||||
{
|
{
|
||||||
log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name));
|
log_error("Class doesn't support expand_interfaces (module: `%s')!\n", id2cstr(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, bool mayfail)
|
RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, bool mayfail)
|
||||||
|
|
|
@ -1160,7 +1160,7 @@ public:
|
||||||
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail = false);
|
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail = false);
|
||||||
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false);
|
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false);
|
||||||
virtual size_t count_id(RTLIL::IdString id);
|
virtual size_t count_id(RTLIL::IdString id);
|
||||||
virtual void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
|
virtual void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
|
||||||
|
|
||||||
virtual void sort();
|
virtual void sort();
|
||||||
virtual void check();
|
virtual void check();
|
||||||
|
|
|
@ -554,7 +554,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||||
|
|
||||||
// If any interface instances or interface ports were found in the module, we need to rederive it completely:
|
// If any interface instances or interface ports were found in the module, we need to rederive it completely:
|
||||||
if ((if_expander.interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute(ID::interfaces_replaced_in_module)) {
|
if ((if_expander.interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute(ID::interfaces_replaced_in_module)) {
|
||||||
module->reprocess_module(design, if_expander.interfaces_in_module);
|
module->expand_interfaces(design, if_expander.interfaces_in_module);
|
||||||
return did_something;
|
return did_something;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue