mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Added support for bus interfaces to "read_liberty -lib"
This commit is contained in:
		
							parent
							
								
									0ead5a9e44
								
							
						
					
					
						commit
						13a03b84d4
					
				
					 1 changed files with 77 additions and 1 deletions
				
			
		|  | @ -469,6 +469,46 @@ struct LibertyFrontend : public Frontend { | ||||||
| 		LibertyParser parser(*f); | 		LibertyParser parser(*f); | ||||||
| 		int cell_count = 0; | 		int cell_count = 0; | ||||||
| 
 | 
 | ||||||
|  | 		std::map<std::string, std::tuple<int, int, bool>> type_map; | ||||||
|  | 
 | ||||||
|  | 		for (auto type_node : parser.ast->children) | ||||||
|  | 		{ | ||||||
|  | 			if (type_node->id != "type" || type_node->args.size() != 1) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			std::string type_name = type_node->args.at(0); | ||||||
|  | 			int bit_width = -1, bit_from = -1, bit_to = -1; | ||||||
|  | 			bool upto = false; | ||||||
|  | 
 | ||||||
|  | 			for (auto child : type_node->children) | ||||||
|  | 			{ | ||||||
|  | 				if (child->id == "base_type" && child->value != "array") | ||||||
|  | 					goto next_type; | ||||||
|  | 
 | ||||||
|  | 				if (child->id == "data_type" && child->value != "bit") | ||||||
|  | 					goto next_type; | ||||||
|  | 
 | ||||||
|  | 				if (child->id == "bit_width") | ||||||
|  | 					bit_width = atoi(child->value.c_str()); | ||||||
|  | 
 | ||||||
|  | 				if (child->id == "bit_from") | ||||||
|  | 					bit_from = atoi(child->value.c_str()); | ||||||
|  | 
 | ||||||
|  | 				if (child->id == "bit_to") | ||||||
|  | 					bit_to = atoi(child->value.c_str()); | ||||||
|  | 
 | ||||||
|  | 				if (child->id == "downto" && (child->value == "0" || child->value == "false" || child->value == "FALSE")) | ||||||
|  | 					upto = true; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (bit_width != (std::max(bit_from, bit_to) - std::min(bit_from, bit_to) + 1)) | ||||||
|  | 				log_error("Incompatible array type '%s': bit_width=%d, bit_from=%d, bit_to=%d.\n", | ||||||
|  | 						type_name.c_str(), bit_width, bit_from, bit_to); | ||||||
|  | 
 | ||||||
|  | 			type_map[type_name] = std::tuple<int, int, bool>(bit_width, std::min(bit_from, bit_to), upto); | ||||||
|  | 		next_type:; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		for (auto cell : parser.ast->children) | 		for (auto cell : parser.ast->children) | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->id != "cell" || cell->args.size() != 1) | 			if (cell->id != "cell" || cell->args.size() != 1) | ||||||
|  | @ -494,13 +534,14 @@ struct LibertyFrontend : public Frontend { | ||||||
| 				module->attributes[attr] = 1; | 				module->attributes[attr] = 1; | ||||||
| 
 | 
 | ||||||
| 			for (auto node : cell->children) | 			for (auto node : cell->children) | ||||||
|  | 			{ | ||||||
| 				if (node->id == "pin" && node->args.size() == 1) { | 				if (node->id == "pin" && node->args.size() == 1) { | ||||||
| 					LibertyAst *dir = node->find("direction"); | 					LibertyAst *dir = node->find("direction"); | ||||||
| 					if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "inout" && dir->value != "internal")) | 					if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "inout" && dir->value != "internal")) | ||||||
| 					{ | 					{ | ||||||
| 						if (!flag_ignore_miss_dir) | 						if (!flag_ignore_miss_dir) | ||||||
| 						{ | 						{ | ||||||
| 							log_error("Missing or invalid direction for pin %s of cell %s.\n", node->args.at(0).c_str(), log_id(module->name)); | 							log_error("Missing or invalid direction for pin %s on cell %s.\n", node->args.at(0).c_str(), log_id(module->name)); | ||||||
| 						} else { | 						} else { | ||||||
| 							log("Ignoring cell %s with missing or invalid direction for pin %s.\n", log_id(module->name), node->args.at(0).c_str()); | 							log("Ignoring cell %s with missing or invalid direction for pin %s.\n", log_id(module->name), node->args.at(0).c_str()); | ||||||
| 							delete module; | 							delete module; | ||||||
|  | @ -511,6 +552,41 @@ struct LibertyFrontend : public Frontend { | ||||||
| 						module->addWire(RTLIL::escape_id(node->args.at(0))); | 						module->addWire(RTLIL::escape_id(node->args.at(0))); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | 				if (node->id == "bus" && node->args.size() == 1) | ||||||
|  | 				{ | ||||||
|  | 					if (!flag_lib) | ||||||
|  | 						log_error("Error in cell %s: bus interfaces are only supported in -lib mode.\n", log_id(cell_name)); | ||||||
|  | 
 | ||||||
|  | 					LibertyAst *dir = node->find("direction"); | ||||||
|  | 
 | ||||||
|  | 					if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "inout" && dir->value != "internal")) | ||||||
|  | 						log_error("Missing or invalid direction for bus %s on cell %s.\n", node->args.at(0).c_str(), log_id(module->name)); | ||||||
|  | 
 | ||||||
|  | 					if (dir->value == "internal") | ||||||
|  | 						continue; | ||||||
|  | 
 | ||||||
|  | 					LibertyAst *bus_type_node = node->find("bus_type"); | ||||||
|  | 
 | ||||||
|  | 					if (!bus_type_node || !type_map.count(bus_type_node->value)) | ||||||
|  | 						log_error("Unkown or unsupported type for bus interface %s on cell %s.\n", | ||||||
|  | 								node->args.at(0).c_str(), log_id(cell_name)); | ||||||
|  | 
 | ||||||
|  | 					int bus_type_width = std::get<0>(type_map.at(bus_type_node->value)); | ||||||
|  | 					int bus_type_offset = std::get<1>(type_map.at(bus_type_node->value)); | ||||||
|  | 					bool bus_type_upto = std::get<2>(type_map.at(bus_type_node->value)); | ||||||
|  | 
 | ||||||
|  | 					Wire *wire = module->addWire(RTLIL::escape_id(node->args.at(0)), bus_type_width); | ||||||
|  | 					wire->start_offset = bus_type_offset; | ||||||
|  | 					wire->upto = bus_type_upto; | ||||||
|  | 
 | ||||||
|  | 					if (dir->value == "input" || dir->value == "inout") | ||||||
|  | 						wire->port_input = true; | ||||||
|  | 
 | ||||||
|  | 					if (dir->value == "output" || dir->value == "inout") | ||||||
|  | 						wire->port_output = true; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			for (auto node : cell->children) | 			for (auto node : cell->children) | ||||||
| 			{ | 			{ | ||||||
| 				if (!flag_lib) { | 				if (!flag_lib) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue