mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +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); | 		(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…
	
	Add table
		Add a link
		
	
		Reference in a new issue