diff options
author | whitequark <whitequark@whitequark.org> | 2019-01-04 02:46:27 +0000 |
---|---|---|
committer | whitequark <whitequark@whitequark.org> | 2019-01-04 03:30:04 +0000 |
commit | fd21564deb73c6fe19c5985ae5c168f628f190d6 (patch) | |
tree | f66c151cf0dc2d3597849040582e660ed4cd2936 /passes/techmap/flowmap.cc | |
parent | 7850a0c28a2a2d7761d49e23e139a93e837a3cca (diff) | |
download | yosys-fd21564deb73c6fe19c5985ae5c168f628f190d6.tar.gz yosys-fd21564deb73c6fe19c5985ae5c168f628f190d6.tar.bz2 yosys-fd21564deb73c6fe19c5985ae5c168f628f190d6.zip |
flowmap: improve debug graph output. NFC.
Diffstat (limited to 'passes/techmap/flowmap.cc')
-rw-r--r-- | passes/techmap/flowmap.cc | 123 |
1 files changed, 76 insertions, 47 deletions
diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc index adfb70a69..5d6b8b645 100644 --- a/passes/techmap/flowmap.cc +++ b/passes/techmap/flowmap.cc @@ -64,10 +64,10 @@ PRIVATE_NAMESPACE_BEGIN struct GraphStyle { string label; - string color; + string color, fillcolor; - GraphStyle(string label = "", string color = "black") : - label(label), color(color) {} + GraphStyle(string label = "", string color = "black", string fillcolor = "") : + label(label), color(color), fillcolor(fillcolor) {} }; static string dot_escape(string value) @@ -110,13 +110,11 @@ static void dump_dot_graph(string filename, if (outputs[node]) shape = "octagon"; auto prop = node_style(node); - string id; - if (node == SigBit()) - id = "(source)"; - else - id = log_signal(node); - 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()); + string style = ""; + if (!prop.fillcolor.empty()) + style = "filled"; + fprintf(f, " n%d [ shape=%s, fontname=\"Monospace\", label=\"%s\", color=\"%s\", fillcolor=\"%s\", style=\"%s\" ];\n", + 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, " { rank=\"source\"; "); @@ -138,8 +136,8 @@ static void dump_dot_graph(string filename, if (nodes[source] && nodes[sink]) { auto prop = edge_style(source, sink); - fprintf(f, " n%d -> n%d [ label=\"%s\", color=\"%s\" ];\n", - ids[source], ids[sink], dot_escape(prop.label.c_str()).c_str(), prop.color.c_str()); + 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(), prop.fillcolor.c_str()); } } } @@ -164,7 +162,7 @@ struct FlowGraph void dump_dot_graph(string filename) { auto node_style = [&](RTLIL::SigBit node) { - string label; + string label = (node == source) ? "(source)" : log_signal(node); for (auto collapsed_node : collapsed[node]) label += stringf(" %s", log_signal(collapsed_node)); int flow = node_flow[node]; @@ -423,28 +421,46 @@ struct FlowmapWorker 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()) - subgraph = nodes; + if (subgraph_nodes.empty()) + subgraph_nodes = nodes; + if (subgraph_edges.empty()) + subgraph_edges = edges_fw; 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) - label = string("\n<unlabeled>"); + label += "\nl=?"; + else + label += stringf("\nl=%d", labels[node]); + if (cut.first.empty() && cut.second.empty()) + { + if (labels[node] == -1) + return GraphStyle{label}; + string fillcolor = stringf("/set311/%d", 1 + labels[node] % 11); + return GraphStyle{label, "", fillcolor}; + } else - label = stringf("\nl=%d", labels[node]); - color = "black"; - if (cut.first[node]) - color = "blue"; - if (cut.second[node]) - color = "red"; - return GraphStyle{label, color}; + { + 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) { 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) @@ -582,8 +598,8 @@ struct FlowmapWorker if (debug) { - dump_dot_graph("flowmap-init.dot"); - log("Dumped complete combinatorial graph to `flowmap-init.dot`.\n"); + dump_dot_graph("flowmap-initial.dot"); + log("Dumped complete initial graph to `flowmap-initial.dot`.\n"); } pool<RTLIL::SigBit> worklist = nodes; @@ -650,7 +666,7 @@ struct FlowmapWorker if (debug) { 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); flow_graph.dump_dot_graph(stringf("flowmap-%d-flow.dot", debug_num)); log(" Dumped flow graph to `flowmap-%d-flow.dot`.\n", debug_num); @@ -668,17 +684,40 @@ struct FlowmapWorker 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; for (auto label : labels) depth = max(depth, label.second); 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); for (auto input_node : inputs) ce.stop(input_node); @@ -687,10 +726,8 @@ struct FlowmapWorker log("Mapping cells.\n"); pool<RTLIL::SigBit> mapped_nodes; - worklist = outputs; - while (!worklist.empty()) + for (auto node : lut_nodes) { - auto node = worklist.pop(); if (node_origins.count(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); mapped_count++; - + mapped_nodes.insert(node); for (auto gate_node : lut_gates[node]) { auto gate_origin = node_origins[gate_node]; lut->add_strpool_attribute("\\src", gate_origin.cell->get_strpool_attribute("\\src")); packed_count++; } - 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(); |