mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Documentation improvements etc.
- Mention new feature in the SystemVerilog section in the README file - Commented changes much better - Rename a few signals to make it clearer - Prevent warning for unused signals in an easier way - Add myself as copyright holder to 2 files - Fix one potential memory leak (delete 'wire' if not in modport)
This commit is contained in:
		
							parent
							
								
									a36d1701dd
								
							
						
					
					
						commit
						c50afc4246
					
				
					 5 changed files with 77 additions and 38 deletions
				
			
		|  | @ -452,6 +452,9 @@ from SystemVerilog: | ||||||
|   into a design with ``read_verilog``, all its packages are available to |   into a design with ``read_verilog``, all its packages are available to | ||||||
|   SystemVerilog files being read into the same design afterwards. |   SystemVerilog files being read into the same design afterwards. | ||||||
| 
 | 
 | ||||||
|  | - SystemVerilog interfaces (SVIs) are supported. Modports for specifying whether | ||||||
|  |   ports are inputs or outputs are supported. | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| Building the documentation | Building the documentation | ||||||
| ========================== | ========================== | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
|  *  yosys -- Yosys Open SYnthesis Suite |  *  yosys -- Yosys Open SYnthesis Suite | ||||||
|  * |  * | ||||||
|  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> |  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> | ||||||
|  |  *  Copyright (C) 2018  Ruben Undheim <ruben.undheim@gmail.com> | ||||||
|  * |  * | ||||||
|  *  Permission to use, copy, modify, and/or distribute this software for any |  *  Permission to use, copy, modify, and/or distribute this software for any | ||||||
|  *  purpose with or without fee is hereby granted, provided that the above |  *  purpose with or without fee is hereby granted, provided that the above | ||||||
|  | @ -1086,6 +1087,8 @@ AstModule::~AstModule() | ||||||
| 		delete ast; | 		delete ast; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // 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, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces) | void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces) | ||||||
| { | { | ||||||
| 	bool is_top = false; | 	bool is_top = false; | ||||||
|  | @ -1101,23 +1104,33 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT | ||||||
| 			new_ast->children.push_back(wire); | 			new_ast->children.push_back(wire); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	// The old module will be deleted. Rename and mark for deletion:
 | ||||||
| 	std::string original_name = this->name.str(); | 	std::string original_name = this->name.str(); | ||||||
| 	std::string changed_name = original_name + "_before_replacing_local_interfaces"; | 	std::string changed_name = original_name + "_before_replacing_local_interfaces"; | ||||||
| 	design->rename(this, changed_name); | 	design->rename(this, changed_name); | ||||||
| 	this->set_bool_attribute("\\to_delete"); | 	this->set_bool_attribute("\\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.
 | ||||||
| 	if (this->get_bool_attribute("\\initial_top")) { | 	if (this->get_bool_attribute("\\initial_top")) { | ||||||
| 		this->attributes.erase("\\initial_top"); | 		this->attributes.erase("\\initial_top"); | ||||||
| 		is_top = true; | 		is_top = true; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	// Generate RTLIL from AST for the new module and add to the design:
 | ||||||
| 	AstModule *newmod = process_module(new_ast, false); | 	AstModule *newmod = process_module(new_ast, false); | ||||||
| 	design->add(newmod); | 	design->add(newmod); | ||||||
| 	RTLIL::Module* mod = design->module(original_name); | 	RTLIL::Module* mod = design->module(original_name); | ||||||
| 	if (is_top) | 	if (is_top) | ||||||
| 		mod->set_bool_attribute("\\top"); | 		mod->set_bool_attribute("\\top"); | ||||||
|  | 
 | ||||||
|  | 	// Set the attribute "interfaces_replaced_in_module" so that it does not happen again.
 | ||||||
| 	mod->set_bool_attribute("\\interfaces_replaced_in_module"); | 	mod->set_bool_attribute("\\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
 | ||||||
|  | // This method is used to explode the interface when the interface is a port of the module (not instantiated inside)
 | ||||||
| RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) | RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) | ||||||
| { | { | ||||||
| 	AstNode *new_ast = NULL; | 	AstNode *new_ast = NULL; | ||||||
|  | @ -1140,9 +1153,12 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R | ||||||
| 
 | 
 | ||||||
| 	if (!design->has(modname)) { | 	if (!design->has(modname)) { | ||||||
| 		new_ast->str = modname; | 		new_ast->str = modname; | ||||||
|  | 
 | ||||||
|  | 		// Iterate over all interfaces which are ports in this module:
 | ||||||
| 		for(auto &intf : interfaces) { | 		for(auto &intf : interfaces) { | ||||||
| 			RTLIL::Module * intfmodule = intf.second; | 			RTLIL::Module * intfmodule = intf.second; | ||||||
| 			std::string intfname = intf.first.str(); | 			std::string intfname = intf.first.str(); | ||||||
|  | 			// Check if a modport applies for the interface port:
 | ||||||
| 			AstNode *modport = NULL; | 			AstNode *modport = NULL; | ||||||
| 			if (modports.count(intfname) > 0) { | 			if (modports.count(intfname) > 0) { | ||||||
| 				std::string interface_modport = modports.at(intfname).str(); | 				std::string interface_modport = modports.at(intfname).str(); | ||||||
|  | @ -1150,12 +1166,13 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R | ||||||
| 				AstNode *ast_node_of_interface = ast_module_of_interface->ast; | 				AstNode *ast_node_of_interface = ast_module_of_interface->ast; | ||||||
| 				for (auto &ch : ast_node_of_interface->children) { | 				for (auto &ch : ast_node_of_interface->children) { | ||||||
| 					if (ch->type == AST_MODPORT) { | 					if (ch->type == AST_MODPORT) { | ||||||
| 						if (ch->str == interface_modport) { | 						if (ch->str == interface_modport) { // Modport found
 | ||||||
| 							modport = ch; | 							modport = ch; | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 			// Iterate over all wires in the interface and add them to the module:
 | ||||||
| 			for (auto &wire_it : intfmodule->wires_){ | 			for (auto &wire_it : intfmodule->wires_){ | ||||||
| 				AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(wire_it.second->width -1, true), AstNode::mkconst_int(0, true))); | 				AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(wire_it.second->width -1, true), AstNode::mkconst_int(0, true))); | ||||||
| 				std::string origname = log_id(wire_it.first); | 				std::string origname = log_id(wire_it.first); | ||||||
|  | @ -1163,10 +1180,11 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R | ||||||
| 				wire->str = newname; | 				wire->str = newname; | ||||||
| 				if (modport != NULL) { | 				if (modport != NULL) { | ||||||
| 					bool found_in_modport = false; | 					bool found_in_modport = false; | ||||||
|  | 					// Search for the current wire in the wire list for the current modport
 | ||||||
| 					for (auto &ch : modport->children) { | 					for (auto &ch : modport->children) { | ||||||
| 						if (ch->type == AST_MODPORTMEMBER) { | 						if (ch->type == AST_MODPORTMEMBER) { | ||||||
| 							std::string compare_name = "\\" + origname; | 							std::string compare_name = "\\" + origname; | ||||||
| 							if (ch->str == compare_name) { | 							if (ch->str == compare_name) { // Found signal. The modport decides whether it is input or output
 | ||||||
| 								found_in_modport = true; | 								found_in_modport = true; | ||||||
| 								wire->is_input = ch->is_input; | 								wire->is_input = ch->is_input; | ||||||
| 								wire->is_output = ch->is_output; | 								wire->is_output = ch->is_output; | ||||||
|  | @ -1174,9 +1192,12 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R | ||||||
| 							} | 							} | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 					if (found_in_modport) { // If not found in modport, do not create port
 | 					if (found_in_modport) { | ||||||
| 						new_ast->children.push_back(wire); | 						new_ast->children.push_back(wire); | ||||||
| 					} | 					} | ||||||
|  | 					else { // If not found in modport, do not create port
 | ||||||
|  | 						delete wire; | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 				else { // If no modport, set inout
 | 				else { // If no modport, set inout
 | ||||||
| 					wire->is_input = true; | 					wire->is_input = true; | ||||||
|  | @ -1191,10 +1212,13 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R | ||||||
| 
 | 
 | ||||||
| 		RTLIL::Module* mod = design->module(modname); | 		RTLIL::Module* mod = design->module(modname); | ||||||
| 
 | 
 | ||||||
|  | 		// Now that the interfaces have been exploded, we can delete the dummy port related to every interface.
 | ||||||
| 		for(auto &intf : interfaces) { | 		for(auto &intf : interfaces) { | ||||||
| 			if(mod->wires_.count(intf.first)) { | 			if(mod->wires_.count(intf.first)) { | ||||||
| 				mod->wires_.erase(intf.first); | 				mod->wires_.erase(intf.first); | ||||||
| 				mod->fixup_ports(); | 				mod->fixup_ports(); | ||||||
|  | 				// We copy the cell of the interface to the sub-module such that it can further be found if it is propagated
 | ||||||
|  | 				// down to sub-sub-modules etc.
 | ||||||
| 				RTLIL::Cell * new_subcell = mod->addCell(intf.first, intf.second->name); | 				RTLIL::Cell * new_subcell = mod->addCell(intf.first, intf.second->name); | ||||||
| 				new_subcell->set_bool_attribute("\\is_interface"); | 				new_subcell->set_bool_attribute("\\is_interface"); | ||||||
| 			} | 			} | ||||||
|  | @ -1203,6 +1227,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		// If any interfaces were replaced, set the attribute 'interfaces_replaced_in_module':
 | ||||||
| 		if (interfaces.size() > 0) { | 		if (interfaces.size() > 0) { | ||||||
| 			mod->set_bool_attribute("\\interfaces_replaced_in_module"); | 			mod->set_bool_attribute("\\interfaces_replaced_in_module"); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -857,7 +857,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | ||||||
| 	case AST_MODPORTMEMBER: | 	case AST_MODPORTMEMBER: | ||||||
| 		break; | 		break; | ||||||
| 	case AST_INTERFACEPORT: { | 	case AST_INTERFACEPORT: { | ||||||
| 		// If a port in a module with unknown type is found, mark it as "is_interface=true"
 | 		// If a port in a module with unknown type is found, mark it with the attribute 'is_interface'
 | ||||||
| 		// This is used by the hierarchy pass to know when it can replace interface connection with the individual
 | 		// This is used by the hierarchy pass to know when it can replace interface connection with the individual
 | ||||||
| 		// signals.
 | 		// signals.
 | ||||||
| 		RTLIL::Wire *wire = current_module->addWire(str, 1); | 		RTLIL::Wire *wire = current_module->addWire(str, 1); | ||||||
|  | @ -872,7 +872,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | ||||||
| 				if(children[i]->type == AST_INTERFACEPORTTYPE) { | 				if(children[i]->type == AST_INTERFACEPORTTYPE) { | ||||||
| 					std::string name_type = children[i]->str; | 					std::string name_type = children[i]->str; | ||||||
| 					size_t ndots = std::count(name_type.begin(), name_type.end(), '.'); | 					size_t ndots = std::count(name_type.begin(), name_type.end(), '.'); | ||||||
| 					if (ndots == 0) { | 					// Separate the interface instance name from any modports:
 | ||||||
|  | 					if (ndots == 0) { // Does not have modport
 | ||||||
| 						wire->attributes["\\interface_type"] = name_type; | 						wire->attributes["\\interface_type"] = name_type; | ||||||
| 					} | 					} | ||||||
| 					else { | 					else { | ||||||
|  | @ -882,11 +883,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | ||||||
| 						while(std::getline(name_type_stream, segment, '.')) { | 						while(std::getline(name_type_stream, segment, '.')) { | ||||||
| 							seglist.push_back(segment); | 							seglist.push_back(segment); | ||||||
| 						} | 						} | ||||||
| 						if (ndots == 1) { | 						if (ndots == 1) { // Has modport
 | ||||||
| 							wire->attributes["\\interface_type"] = seglist[0]; | 							wire->attributes["\\interface_type"] = seglist[0]; | ||||||
| 							wire->attributes["\\interface_modport"] = seglist[1]; | 							wire->attributes["\\interface_modport"] = seglist[1]; | ||||||
| 						} | 						} | ||||||
| 						else { | 						else { // Erroneous port type
 | ||||||
| 							log_error("More than two '.' in signal port type (%s)\n", name_type.c_str()); | 							log_error("More than two '.' in signal port type (%s)\n", name_type.c_str()); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  | @ -1034,7 +1035,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | ||||||
| 				log_file_error(filename, linenum, "Identifier `%s' does map to an unexpanded memory!\n", | 				log_file_error(filename, linenum, "Identifier `%s' does map to an unexpanded memory!\n", | ||||||
| 					       str.c_str()); | 					       str.c_str()); | ||||||
| 
 | 
 | ||||||
| 			// If identifier is an interface, create a RTLIL::SigSpec object and set is_interface to true.
 | 			// If identifier is an interface, create a RTLIL::SigSpec with a dummy wire with a attribute called 'is_interface'
 | ||||||
| 			// This makes it possible for the hierarchy pass to see what are interface connections and then replace them
 | 			// This makes it possible for the hierarchy pass to see what are interface connections and then replace them
 | ||||||
| 			// with the individual signals:
 | 			// with the individual signals:
 | ||||||
| 			if (is_interface) { | 			if (is_interface) { | ||||||
|  | @ -1495,6 +1496,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | ||||||
| 
 | 
 | ||||||
| 			RTLIL::Cell *cell = current_module->addCell(str, ""); | 			RTLIL::Cell *cell = current_module->addCell(str, ""); | ||||||
| 			cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); | 			cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); | ||||||
|  | 			// Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass
 | ||||||
| 			cell->set_bool_attribute("\\module_not_derived"); | 			cell->set_bool_attribute("\\module_not_derived"); | ||||||
| 
 | 
 | ||||||
| 			for (auto it = children.begin(); it != children.end(); it++) { | 			for (auto it = children.begin(); it != children.end(); it++) { | ||||||
|  |  | ||||||
|  | @ -639,11 +639,9 @@ RTLIL::Module::~Module() | ||||||
| 		delete it->second; | 		delete it->second; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RTLIL::Module::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) | void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>) | ||||||
| { | { | ||||||
| 	log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name)); | 	log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name)); | ||||||
| 	(void)local_interfaces; // To remove build warning
 |  | ||||||
| 	(void)design;           // To remove build warning
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, bool mayfail) | RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, bool mayfail) | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
|  *  yosys -- Yosys Open SYnthesis Suite |  *  yosys -- Yosys Open SYnthesis Suite | ||||||
|  * |  * | ||||||
|  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> |  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> | ||||||
|  |  *  Copyright (C) 2018  Ruben Undheim <ruben.undheim@gmail.com> | ||||||
|  * |  * | ||||||
|  *  Permission to use, copy, modify, and/or distribute this software for any |  *  Permission to use, copy, modify, and/or distribute this software for any | ||||||
|  *  purpose with or without fee is hereby granted, provided that the above |  *  purpose with or without fee is hereby granted, provided that the above | ||||||
|  | @ -145,6 +146,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check | ||||||
| 	std::map<RTLIL::Cell*, std::pair<int, int>> array_cells; | 	std::map<RTLIL::Cell*, std::pair<int, int>> array_cells; | ||||||
| 	std::string filename; | 	std::string filename; | ||||||
| 
 | 
 | ||||||
|  | 	// Always keep track of all derived interfaces available in the current module in 'interfaces_in_module':
 | ||||||
| 	dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module; | 	dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module; | ||||||
| 	for (auto &cell_it : module->cells_) | 	for (auto &cell_it : module->cells_) | ||||||
| 	{ | 	{ | ||||||
|  | @ -222,27 +224,29 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check | ||||||
| 		RTLIL::Module *mod = design->module(cell->type); | 		RTLIL::Module *mod = design->module(cell->type); | ||||||
| 
 | 
 | ||||||
| 		// Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to
 | 		// Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to
 | ||||||
| 		// some lists, so that they can be replaced further down:
 | 		// some lists, so that the ports for sub-modules can be replaced further down:
 | ||||||
| 		for (auto &conn : cell->connections()) { | 		for (auto &conn : cell->connections()) { | ||||||
| 			if(mod->wires_.count(conn.first) != 0 && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list
 | 			if(mod->wires_.count(conn.first) != 0 && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list
 | ||||||
| 				//const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_type");
 | 				//const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_type");
 | ||||||
| 				//for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module
 | 				//for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module (not crucially important, but good for robustness)
 | ||||||
| 				//}
 | 				//}
 | ||||||
|  | 
 | ||||||
|  | 				// Find if the sub-module has set a modport for the current interface connection:
 | ||||||
| 				const pool<string> &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_modport"); | 				const pool<string> &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_modport"); | ||||||
| 				std::string interface_modport = ""; | 				std::string interface_modport = ""; | ||||||
| 				for (auto &d : interface_modport_pool) { | 				for (auto &d : interface_modport_pool) { | ||||||
| 					interface_modport = "\\" + d; | 					interface_modport = "\\" + d; | ||||||
| 				} | 				} | ||||||
| 				if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { | 				if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { // Check if the connected wire is a potential interface in the parent module
 | ||||||
| 					std::string interface_name_str = conn.second.bits()[0].wire->name.str(); | 					std::string interface_name_str = conn.second.bits()[0].wire->name.str(); | ||||||
| 					interface_name_str.replace(0,23,""); | 					interface_name_str.replace(0,23,""); // Strip the prefix '$dummywireforinterface' from the dummy wire to get the name
 | ||||||
| 					interface_name_str = "\\" + interface_name_str; | 					interface_name_str = "\\" + interface_name_str; | ||||||
| 					RTLIL::IdString interface_name = interface_name_str; | 					RTLIL::IdString interface_name = interface_name_str; | ||||||
| 					bool will_do_step = false; | 					bool not_found_interface = false; | ||||||
| 					if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { | 					if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either
 | ||||||
| 						if (interfaces_in_module.count(interface_name) > 0) { // Check if the interface instance is present in module
 | 						if (interfaces_in_module.count(interface_name) > 0) { // Check if the interface instance is present in module
 | ||||||
| 							RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name); | 							RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name); | ||||||
| 						for (auto &mod_wire : mod_replace_ports->wires_) { | 							for (auto &mod_wire : mod_replace_ports->wires_) { // Go over all wires in interface, and add replacements to lists.
 | ||||||
| 								std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire.first); | 								std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire.first); | ||||||
| 								std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first); | 								std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first); | ||||||
| 								connections_to_add_name.push_back(RTLIL::IdString(signal_name1)); | 								connections_to_add_name.push_back(RTLIL::IdString(signal_name1)); | ||||||
|  | @ -256,16 +260,18 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check | ||||||
| 							} | 							} | ||||||
| 							connections_to_remove.push_back(conn.first); | 							connections_to_remove.push_back(conn.first); | ||||||
| 							interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name); | 							interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name); | ||||||
|  | 
 | ||||||
|  | 							// Add modports to a dict which will be passed to AstModule::derive
 | ||||||
| 							if (interface_modport != "") { | 							if (interface_modport != "") { | ||||||
| 								modports_used_in_submodule[conn.first] = interface_modport; | 								modports_used_in_submodule[conn.first] = interface_modport; | ||||||
| 							} | 							} | ||||||
| 						} | 						} | ||||||
| 					  else will_do_step = true; | 						else not_found_interface = true; | ||||||
| 					} | 					} | ||||||
| 					else will_do_step = true; | 					else not_found_interface = true; | ||||||
| 					// If the interface instance has not already been derived in the module, we cannot complete at this stage. Set "has_interfaces_not_found"
 | 					// If the interface instance has not already been derived in the module, we cannot complete at this stage. Set "has_interfaces_not_found"
 | ||||||
| 					// which will delay the expansion of this cell:
 | 					// which will delay the expansion of this cell:
 | ||||||
| 					if (will_do_step) { | 					if (not_found_interface) { | ||||||
| 						// If we have already gone over all cells in this module, and the interface has still not been found - flag it as an error:
 | 						// If we have already gone over all cells in this module, and the interface has still not been found - flag it as an error:
 | ||||||
| 						if(!(module->get_bool_attribute("\\cells_not_processed"))) { | 						if(!(module->get_bool_attribute("\\cells_not_processed"))) { | ||||||
| 							log_warning("Could not find interface instance for `%s' in `%s'\n", log_id(interface_name), log_id(module)); | 							log_warning("Could not find interface instance for `%s' in `%s'\n", log_id(interface_name), log_id(module)); | ||||||
|  | @ -348,13 +354,16 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check | ||||||
| 				interfaces_in_module[cell->name] = derived_module; | 				interfaces_in_module[cell->name] = derived_module; | ||||||
| 				did_something = true; | 				did_something = true; | ||||||
| 			} | 			} | ||||||
| 		// We unset 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell)
 | 		// We clear 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell)
 | ||||||
| 		cell->attributes.erase("\\module_not_derived"); | 		cell->attributes.erase("\\module_not_derived"); | ||||||
| 	} | 	} | ||||||
| 	// Setting a flag such that it can be known that we have been through all cells at least once, such that we can know whether to flag
 | 	// Clear the attribute 'cells_not_processed' such that it can be known that we
 | ||||||
| 	// an error because of interface instances not found:
 | 	// have been through all cells at least once, and that we can know whether
 | ||||||
|  | 	// to flag an error because of interface instances not found:
 | ||||||
| 	module->attributes.erase("\\cells_not_processed"); | 	module->attributes.erase("\\cells_not_processed"); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 	// If any interface instances were found in the module, we need to rederive it completely:
 | ||||||
| 	if (interfaces_in_module.size() > 0 && !module->get_bool_attribute("\\interfaces_replaced_in_module")) { | 	if (interfaces_in_module.size() > 0 && !module->get_bool_attribute("\\interfaces_replaced_in_module")) { | ||||||
| 		module->reprocess_module(design, interfaces_in_module); | 		module->reprocess_module(design, interfaces_in_module); | ||||||
| 		return did_something; | 		return did_something; | ||||||
|  | @ -736,6 +745,7 @@ struct HierarchyPass : public Pass { | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 			// The top module might have changed if interface instances have been detected in it:
 | ||||||
| 			RTLIL::Module *tmp_top_mod = check_if_top_has_changed(design, top_mod); | 			RTLIL::Module *tmp_top_mod = check_if_top_has_changed(design, top_mod); | ||||||
| 			if (tmp_top_mod != NULL) { | 			if (tmp_top_mod != NULL) { | ||||||
| 				if (tmp_top_mod != top_mod){ | 				if (tmp_top_mod != top_mod){ | ||||||
|  | @ -744,6 +754,7 @@ struct HierarchyPass : public Pass { | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			// Delete modules marked as 'to_delete':
 | ||||||
| 			std::vector<RTLIL::Module *> modules_to_delete; | 			std::vector<RTLIL::Module *> modules_to_delete; | ||||||
| 			for(auto &mod_it : design->modules_) { | 			for(auto &mod_it : design->modules_) { | ||||||
| 				if (mod_it.second->get_bool_attribute("\\to_delete")) { | 				if (mod_it.second->get_bool_attribute("\\to_delete")) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue