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);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
@ -936,9 +936,9 @@ void RTLIL::Module::makeblackbox()
|
|||
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)
|
||||
|
|
|
@ -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, 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 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 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 ((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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue