mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +00:00
flowmap: improve debug graph output. NFC.
This commit is contained in:
parent
7850a0c28a
commit
fd21564deb
|
@ -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…
Reference in a new issue