mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-25 10:05:33 +00:00
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
5 changed files with 61 additions and 28 deletions
|
@ -983,8 +983,7 @@ static bool param_has_no_default(const AstNode *param) {
|
|||
(children.size() == 1 && children[0]->type == AST_RANGE);
|
||||
}
|
||||
|
||||
// create and add a new AstModule from an AST_MODULE AST node
|
||||
static void process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false)
|
||||
static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false)
|
||||
{
|
||||
log_assert(current_scope.empty());
|
||||
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);
|
||||
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
|
||||
|
@ -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
|
||||
// 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();
|
||||
|
||||
bool is_top = false;
|
||||
AstNode *new_ast = ast->clone();
|
||||
for (auto &intf : local_interfaces) {
|
||||
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:
|
||||
std::string original_name = this->name.str();
|
||||
std::string changed_name = original_name + "_before_replacing_local_interfaces";
|
||||
design->rename(this, changed_name);
|
||||
this->set_bool_attribute(ID::to_delete);
|
||||
// Generate RTLIL from AST for the new module and add to the design,
|
||||
// renaming this module to move it out of the way.
|
||||
RTLIL::Module* new_module =
|
||||
process_and_replace_module(design, this, new_ast, ast_before_replacing_interface_ports);
|
||||
|
||||
// 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.
|
||||
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);
|
||||
delete new_ast;
|
||||
|
||||
// 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
|
||||
|
|
|
@ -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, 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);
|
||||
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;
|
||||
void loadconfig() const;
|
||||
};
|
||||
|
@ -395,6 +395,18 @@ namespace AST_INTERNAL
|
|||
extern dict<std::string, pool<int>> current_memwr_visible;
|
||||
struct LookaheadRewriter;
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue