mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	flowmap: improve debug graph output. NFC.
This commit is contained in:
		
							parent
							
								
									7850a0c28a
								
							
						
					
					
						commit
						fd21564deb
					
				
					 1 changed files with 76 additions and 47 deletions
				
			
		|  | @ -64,10 +64,10 @@ PRIVATE_NAMESPACE_BEGIN | ||||||
| struct GraphStyle | struct GraphStyle | ||||||
| { | { | ||||||
| 	string label; | 	string label; | ||||||
| 	string color; | 	string color, fillcolor; | ||||||
| 
 | 
 | ||||||
| 	GraphStyle(string label = "", string color = "black") : | 	GraphStyle(string label = "", string color = "black", string fillcolor = "") : | ||||||
| 		label(label), color(color) {} | 		label(label), color(color), fillcolor(fillcolor) {} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static string dot_escape(string value) | static string dot_escape(string value) | ||||||
|  | @ -110,13 +110,11 @@ static void dump_dot_graph(string filename, | ||||||
| 		if (outputs[node]) | 		if (outputs[node]) | ||||||
| 			shape = "octagon"; | 			shape = "octagon"; | ||||||
| 		auto prop = node_style(node); | 		auto prop = node_style(node); | ||||||
| 		string id; | 		string style = ""; | ||||||
| 		if (node == SigBit()) | 		if (!prop.fillcolor.empty()) | ||||||
| 			id = "(source)"; | 			style = "filled"; | ||||||
| 		else | 		fprintf(f, "  n%d [ shape=%s, fontname=\"Monospace\", label=\"%s\", color=\"%s\", fillcolor=\"%s\", style=\"%s\" ];\n", | ||||||
| 			id = log_signal(node); | 		        ids[node], shape.c_str(), dot_escape(prop.label.c_str()).c_str(), prop.color.c_str(), prop.fillcolor.c_str(), style.c_str()); | ||||||
| 		fprintf(f, "  n%d [ shape=%s, fontname=\"Monospace\", label=\"%s%s\", color=\"%s\" ];\n", |  | ||||||
| 		        ids[node], shape.c_str(), dot_escape(id).c_str(), dot_escape(prop.label.c_str()).c_str(), prop.color.c_str()); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fprintf(f, "  { rank=\"source\"; "); | 	fprintf(f, "  { rank=\"source\"; "); | ||||||
|  | @ -138,8 +136,8 @@ static void dump_dot_graph(string filename, | ||||||
| 			if (nodes[source] && nodes[sink]) | 			if (nodes[source] && nodes[sink]) | ||||||
| 			{ | 			{ | ||||||
| 				auto prop = edge_style(source, sink); | 				auto prop = edge_style(source, sink); | ||||||
| 				fprintf(f, "  n%d -> n%d [ label=\"%s\", color=\"%s\" ];\n", | 				fprintf(f, "  n%d -> n%d [ label=\"%s\", color=\"%s\", fillcolor=\"%s\" ];\n", | ||||||
| 				        ids[source], ids[sink], dot_escape(prop.label.c_str()).c_str(), prop.color.c_str()); | 				        ids[source], ids[sink], dot_escape(prop.label.c_str()).c_str(), prop.color.c_str(), prop.fillcolor.c_str()); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -164,7 +162,7 @@ struct FlowGraph | ||||||
| 	void dump_dot_graph(string filename) | 	void dump_dot_graph(string filename) | ||||||
| 	{ | 	{ | ||||||
| 		auto node_style = [&](RTLIL::SigBit node) { | 		auto node_style = [&](RTLIL::SigBit node) { | ||||||
| 			string label; | 			string label = (node == source) ? "(source)" : log_signal(node); | ||||||
| 			for (auto collapsed_node : collapsed[node]) | 			for (auto collapsed_node : collapsed[node]) | ||||||
| 				label += stringf(" %s", log_signal(collapsed_node)); | 				label += stringf(" %s", log_signal(collapsed_node)); | ||||||
| 			int flow = node_flow[node]; | 			int flow = node_flow[node]; | ||||||
|  | @ -423,28 +421,46 @@ struct FlowmapWorker | ||||||
| 
 | 
 | ||||||
| 	int mapped_count = 0, packed_count = 0, unique_packed_count = 0; | 	int mapped_count = 0, packed_count = 0, unique_packed_count = 0; | ||||||
| 
 | 
 | ||||||
| 	void dump_dot_graph(string filename, pool<RTLIL::SigBit> subgraph = {}, pair<pool<RTLIL::SigBit>, pool<RTLIL::SigBit>> cut = {}) | 	void dump_dot_graph(string filename, | ||||||
|  | 	                    pool<RTLIL::SigBit> subgraph_nodes = {}, dict<RTLIL::SigBit, pool<RTLIL::SigBit>> subgraph_edges = {}, | ||||||
|  | 	                    pair<pool<RTLIL::SigBit>, pool<RTLIL::SigBit>> cut = {}, | ||||||
|  | 	                    dict<RTLIL::SigBit, pool<RTLIL::SigBit>> collapsed = {}) | ||||||
| 	{ | 	{ | ||||||
| 		if (subgraph.empty()) | 		if (subgraph_nodes.empty()) | ||||||
| 			subgraph = nodes; | 			subgraph_nodes = nodes; | ||||||
|  | 		if (subgraph_edges.empty()) | ||||||
|  | 			subgraph_edges = edges_fw; | ||||||
| 
 | 
 | ||||||
| 		auto node_style = [&](RTLIL::SigBit node) { | 		auto node_style = [&](RTLIL::SigBit node) { | ||||||
| 			string label, color; | 			string label = log_signal(node); | ||||||
|  | 			for (auto collapsed_node : collapsed[node]) | ||||||
|  | 				if (collapsed_node != node) | ||||||
|  | 					label += stringf(" %s", log_signal(collapsed_node)); | ||||||
| 			if (labels[node] == -1) | 			if (labels[node] == -1) | ||||||
| 				label = string("\n<unlabeled>"); | 				label += "\nl=?"; | ||||||
| 			else | 			else | ||||||
| 				label = stringf("\nl=%d", labels[node]); | 				label += stringf("\nl=%d", labels[node]); | ||||||
| 			color = "black"; | 			if (cut.first.empty() && cut.second.empty()) | ||||||
| 			if (cut.first[node]) | 			{ | ||||||
| 				color = "blue"; | 				if (labels[node] == -1) | ||||||
| 			if (cut.second[node]) | 					return GraphStyle{label}; | ||||||
| 				color = "red"; | 				string fillcolor = stringf("/set311/%d", 1 + labels[node] % 11); | ||||||
| 			return GraphStyle{label, color}; | 				return GraphStyle{label, "", fillcolor}; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				string color = "black"; | ||||||
|  | 				if (cut.first[node]) | ||||||
|  | 					color = "blue"; | ||||||
|  | 				if (cut.second[node]) | ||||||
|  | 					color = "red"; | ||||||
|  | 				return GraphStyle{label, color}; | ||||||
|  | 			} | ||||||
| 		}; | 		}; | ||||||
| 		auto edge_style = [&](RTLIL::SigBit, RTLIL::SigBit) { | 		auto edge_style = [&](RTLIL::SigBit, RTLIL::SigBit) { | ||||||
| 			return GraphStyle{}; | 			return GraphStyle{}; | ||||||
| 		}; | 		}; | ||||||
| 		::dump_dot_graph(filename, subgraph, edges_fw, inputs, outputs, node_style, edge_style, module->name.str()); | 		::dump_dot_graph(filename, subgraph_nodes, subgraph_edges, inputs, outputs, node_style, edge_style, module->name.str()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	pool<RTLIL::SigBit> find_subgraph(RTLIL::SigBit sink) | 	pool<RTLIL::SigBit> find_subgraph(RTLIL::SigBit sink) | ||||||
|  | @ -582,8 +598,8 @@ struct FlowmapWorker | ||||||
| 
 | 
 | ||||||
| 		if (debug) | 		if (debug) | ||||||
| 		{ | 		{ | ||||||
| 			dump_dot_graph("flowmap-init.dot"); | 			dump_dot_graph("flowmap-initial.dot"); | ||||||
| 			log("Dumped complete combinatorial graph to `flowmap-init.dot`.\n"); | 			log("Dumped complete initial graph to `flowmap-initial.dot`.\n"); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		pool<RTLIL::SigBit> worklist = nodes; | 		pool<RTLIL::SigBit> worklist = nodes; | ||||||
|  | @ -650,7 +666,7 @@ struct FlowmapWorker | ||||||
| 			if (debug) | 			if (debug) | ||||||
| 			{ | 			{ | ||||||
| 				log("  Maximum flow: %d. Assigned label %d.\n", flow, labels[sink]); | 				log("  Maximum flow: %d. Assigned label %d.\n", flow, labels[sink]); | ||||||
| 				dump_dot_graph(stringf("flowmap-%d-sub.dot", debug_num), subgraph, {x, xi}); | 				dump_dot_graph(stringf("flowmap-%d-sub.dot", debug_num), subgraph, {}, {x, xi}); | ||||||
| 				log("  Dumped subgraph to `flowmap-%d-sub.dot`.\n", debug_num); | 				log("  Dumped subgraph to `flowmap-%d-sub.dot`.\n", debug_num); | ||||||
| 				flow_graph.dump_dot_graph(stringf("flowmap-%d-flow.dot", debug_num)); | 				flow_graph.dump_dot_graph(stringf("flowmap-%d-flow.dot", debug_num)); | ||||||
| 				log("  Dumped flow graph to `flowmap-%d-flow.dot`.\n", debug_num); | 				log("  Dumped flow graph to `flowmap-%d-flow.dot`.\n", debug_num); | ||||||
|  | @ -668,17 +684,40 @@ struct FlowmapWorker | ||||||
| 				worklist.insert(sink_succ); | 				worklist.insert(sink_succ); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (debug) |  | ||||||
| 		{ |  | ||||||
| 			dump_dot_graph("flowmap-done.dot"); |  | ||||||
| 			log("Dumped complete combinatorial graph to `flowmap-done.dot`.\n"); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		int depth = 0; | 		int depth = 0; | ||||||
| 		for (auto label : labels) | 		for (auto label : labels) | ||||||
| 			depth = max(depth, label.second); | 			depth = max(depth, label.second); | ||||||
| 		log("Maximum depth: %d levels.\n", depth); | 		log("Maximum depth: %d levels.\n", depth); | ||||||
| 
 | 
 | ||||||
|  | 		if (debug) | ||||||
|  | 		{ | ||||||
|  | 			dump_dot_graph("flowmap-labeled.dot"); | ||||||
|  | 			log("Dumped complete labeled graph to `flowmap-labeled.dot`.\n"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		pool<RTLIL::SigBit> lut_nodes; | ||||||
|  | 		dict<RTLIL::SigBit, pool<RTLIL::SigBit>> lut_edges; | ||||||
|  | 		worklist = outputs; | ||||||
|  | 		while (!worklist.empty()) | ||||||
|  | 		{ | ||||||
|  | 			auto lut_node = worklist.pop(); | ||||||
|  | 			lut_nodes.insert(lut_node); | ||||||
|  | 			for (auto input_node : lut_inputs[lut_node]) | ||||||
|  | 			{ | ||||||
|  | 				lut_edges[input_node].insert(lut_node); | ||||||
|  | 				if (!lut_nodes[input_node] && !inputs[input_node]) | ||||||
|  | 					worklist.insert(input_node); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (debug) | ||||||
|  | 		{ | ||||||
|  | 			pool<RTLIL::SigBit> lut_and_input_nodes = lut_nodes; | ||||||
|  | 			lut_and_input_nodes.insert(inputs.begin(), inputs.end()); | ||||||
|  | 			dump_dot_graph("flowmap-packed.dot", lut_and_input_nodes, lut_edges, {}, lut_gates); | ||||||
|  | 			log("Dumped complete packed graph to `flowmap-packed.dot`.\n"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		ConstEval ce(module); | 		ConstEval ce(module); | ||||||
| 		for (auto input_node : inputs) | 		for (auto input_node : inputs) | ||||||
| 			ce.stop(input_node); | 			ce.stop(input_node); | ||||||
|  | @ -687,10 +726,8 @@ struct FlowmapWorker | ||||||
| 		log("Mapping cells.\n"); | 		log("Mapping cells.\n"); | ||||||
| 
 | 
 | ||||||
| 		pool<RTLIL::SigBit> mapped_nodes; | 		pool<RTLIL::SigBit> mapped_nodes; | ||||||
| 		worklist = outputs; | 		for (auto node : lut_nodes) | ||||||
| 		while (!worklist.empty()) |  | ||||||
| 		{ | 		{ | ||||||
| 			auto node = worklist.pop(); |  | ||||||
| 			if (node_origins.count(node)) | 			if (node_origins.count(node)) | ||||||
| 			{ | 			{ | ||||||
| 				auto origin = node_origins[node]; | 				auto origin = node_origins[node]; | ||||||
|  | @ -750,22 +787,14 @@ struct FlowmapWorker | ||||||
| 
 | 
 | ||||||
| 			RTLIL::Cell *lut = module->addLut(NEW_ID, lut_a, lut_y, lut_table); | 			RTLIL::Cell *lut = module->addLut(NEW_ID, lut_a, lut_y, lut_table); | ||||||
| 			mapped_count++; | 			mapped_count++; | ||||||
| 
 | 			mapped_nodes.insert(node); | ||||||
| 			for (auto gate_node : lut_gates[node]) | 			for (auto gate_node : lut_gates[node]) | ||||||
| 			{ | 			{ | ||||||
| 				auto gate_origin = node_origins[gate_node]; | 				auto gate_origin = node_origins[gate_node]; | ||||||
| 				lut->add_strpool_attribute("\\src", gate_origin.cell->get_strpool_attribute("\\src")); | 				lut->add_strpool_attribute("\\src", gate_origin.cell->get_strpool_attribute("\\src")); | ||||||
| 				packed_count++; | 				packed_count++; | ||||||
| 			} | 			} | ||||||
| 
 |  | ||||||
| 			log("  Packed into a %d-LUT %s.%s.\n", (int)input_nodes.size(), log_id(module), log_id(lut)); | 			log("  Packed into a %d-LUT %s.%s.\n", (int)input_nodes.size(), log_id(module), log_id(lut)); | ||||||
| 
 |  | ||||||
| 			mapped_nodes.insert(node); |  | ||||||
| 			for (auto input_node : input_nodes) |  | ||||||
| 			{ |  | ||||||
| 				if (!mapped_nodes[input_node] && !inputs[input_node]) |  | ||||||
| 					worklist.insert(input_node); |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		unique_packed_count += nodes.size(); | 		unique_packed_count += nodes.size(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue