mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +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 | ||||
|  |  | |||
|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue