protected override PlacementInfo PositionComponents(Dictionary <FIRRTLNode, Point> nodeSizes, Module mod) { PlacementInfo placments = new PlacementInfo(); const int dpi = 96; const int ppi = 72; RootGraph graph = RootGraph.CreateNew("some name??", GraphType.Directed); graph.SafeSetAttribute("rankdir", "LR", "TB"); graph.SafeSetAttribute("ranksep", "7", "0.5"); graph.SafeSetAttribute("nodesep", "1.0", "0.25"); //Add nodes to graph Dictionary <FIRRTLNode, Node> firNodeToNode = new Dictionary <FIRRTLNode, Node>(); Dictionary <Input, string> inputToPort = new Dictionary <Input, string>(); Dictionary <Output, string> outputToPort = new Dictionary <Output, string>(); Dictionary <Input, Node> inputToNode = new Dictionary <Input, Node>(); Dictionary <Output, Node> outputToNode = new Dictionary <Output, Node>(); int nodeCounter = 0; int portName = 0; foreach (var firNode in nodeSizes) { if (firNode.Key == mod) { continue; } string nodeName = $"n{nodeCounter++}"; Node node = graph.GetOrAddNode(nodeName); node.SafeSetAttribute("shape", "record", "ellipse"); node.SafeSetAttribute("width", ((double)firNode.Value.X / dpi).ToString(), "0.75"); node.SafeSetAttribute("height", ((double)firNode.Value.Y / dpi).ToString(), "0.5"); Input[] nodeInputs = firNode.Key.GetInputs(); Output[] nodeOutputs = firNode.Key.GetOutputs(); MakeIntoRecord(node, nodeInputs, nodeOutputs, inputToPort, outputToPort, ref portName); firNodeToNode.Add(firNode.Key, node); foreach (var input in nodeInputs) { inputToNode.Add(input, node); } foreach (var output in nodeOutputs) { outputToNode.Add(output, node); } } Node modInputNode = graph.GetOrAddNode("modInput"); MakeIntoRecord(modInputNode, mod.GetInputs(), Array.Empty <Output>(), inputToPort, outputToPort, ref portName); modInputNode.SafeSetAttribute("rank", "sink", "sink"); Node modOutputNode = graph.GetOrAddNode("modOutput"); MakeIntoRecord(modInputNode, Array.Empty <Input>(), mod.GetOutputs(), inputToPort, outputToPort, ref portName); modOutputNode.SafeSetAttribute("rank", "source", "source"); //Make edges int edgeCounter = 0; foreach (Output output in outputToNode.Keys) { if (!output.IsConnectedToAnything()) { continue; } var from = outputToNode[output]; foreach (var input in output.GetConnectedInputs()) { if (input.Node != null && input.Node is INoPlaceAndRoute) { continue; } if (!inputToNode.ContainsKey(input)) { continue; } var to = inputToNode[input]; var edge = graph.GetOrAddEdge(from, to, (edgeCounter++).ToString()); edge.SafeSetAttribute("tailport", outputToPort[output], " "); edge.SafeSetAttribute("headport", inputToPort[input], " "); } } graph.ComputeLayout(); Dictionary <FIRRTLNode, Rectangle> firNodeRects = new Dictionary <FIRRTLNode, Rectangle>(); foreach (var firToVizNode in firNodeToNode) { var centerF = firToVizNode.Value.Position(); var center = new Point((int)(centerF.X * dpi), (int)(centerF.Y * dpi)) / ppi; var nodeSize = nodeSizes[firToVizNode.Key]; var topLeft = center - (nodeSize / 2); firNodeRects.Add(firToVizNode.Key, new Rectangle(topLeft, nodeSize)); } graph.FreeLayout(); Point min = new Point(int.MaxValue, int.MaxValue); foreach (var rect in firNodeRects.Values) { min = Point.Min(min, rect.Pos); } Point offsetBy = min.Abs(); foreach (var firRect in firNodeRects) { placments.AddNodePlacement(firRect.Key, new Rectangle(offsetBy + firRect.Value.Pos, firRect.Value.Size)); } Point borderPadding = new Point(100, 200); placments.AutoSpacePlacementRanks(mod); placments.AddBorderPadding(borderPadding); return(placments); }
protected override PlacementInfo PositionComponents(Dictionary <FIRRTLNode, Point> nodeSizes, Module mod) { PlacementInfo placments = new PlacementInfo(); Graph <FIRRTLNode> graph = new Graph <FIRRTLNode>(); //Add nodes to graph Dictionary <Input, Node <FIRRTLNode> > inputToNode = new Dictionary <Input, Node <FIRRTLNode> >(); Dictionary <Output, Node <FIRRTLNode> > outputToNode = new Dictionary <Output, Node <FIRRTLNode> >(); foreach (var firNode in nodeSizes.Keys) { var node = new Node <FIRRTLNode>(firNode); graph.AddNode(node); foreach (var input in firNode.GetInputs()) { inputToNode.Add(input, node); } foreach (var output in firNode.GetOutputs()) { outputToNode.Add(output, node); } } List <Node <FIRRTLNode> > modInputNodes = new List <Node <FIRRTLNode> >(); foreach (var input in mod.GetInternalInputs()) { if (!input.IsConnectedToAnything()) { continue; } Node <FIRRTLNode> modInputNode = new Node <FIRRTLNode>(mod); graph.AddNode(modInputNode); inputToNode.Add(input, modInputNode); modInputNodes.Add(modInputNode); } List <Node <FIRRTLNode> > modOutputNodes = new List <Node <FIRRTLNode> >(); foreach (var output in mod.GetInternalOutputs()) { if (!output.IsConnectedToAnything()) { continue; } Node <FIRRTLNode> modOutputNode = new Node <FIRRTLNode>(mod); graph.AddNode(modOutputNode); outputToNode.Add(output, modOutputNode); modOutputNodes.Add(modOutputNode); } //Make edges foreach (Output output in outputToNode.Keys) { if (!output.IsConnectedToAnything()) { continue; } var from = outputToNode[output]; foreach (var input in output.GetConnectedInputs()) { if (input.Node != null && input.Node is INoPlaceAndRoute) { continue; } if (!inputToNode.ContainsKey(input)) { continue; } var to = inputToNode[input]; graph.AddEdge(from, to); } } graph.MakeIndirectConnections(); var placement = GetPlacements(graph); foreach (var modIONode in modInputNodes) { placement.Remove(modIONode); } foreach (var modIONode in modOutputNodes) { placement.Remove(modIONode); } Point min = new Point(int.MaxValue, int.MaxValue); Point max = new Point(int.MinValue, int.MinValue); foreach (var keyVal in placement) { min = Point.Min(min, keyVal.Value); max = Point.Max(max, keyVal.Value); } int columns = max.X - min.X + 1; int rows = max.Y - min.Y + 1; FIRRTLNode[][] nodePlacements = new FIRRTLNode[columns][]; for (int i = 0; i < nodePlacements.Length; i++) { nodePlacements[i] = new FIRRTLNode[rows]; } foreach (var keyVal in placement) { Point pos = keyVal.Value - min; nodePlacements[pos.X][pos.Y] = keyVal.Key.Value; } var xGroups = placement.GroupBy(x => x.Value.X).OrderBy(x => x.Key).ToArray(); var yGroups = placement.GroupBy(x => x.Value.Y).OrderBy(x => x.Key).ToArray(); int[] xOffsets = MakeXOffsets(xGroups, min, columns, nodeSizes, mod); int[] yOffsets = MakeYOffsets(yGroups, min, 72, rows, nodeSizes); for (int x = 0; x < columns; x++) { for (int y = 0; y < rows; y++) { FIRRTLNode node = nodePlacements[x][y]; if (node == null) { continue; } Point pos = new Point(xOffsets[x], yOffsets[y]); placments.AddNodePlacement(node, new Rectangle(pos, nodeSizes[node])); } } Point borderPadding = new Point(100, 200); placments.AutoSpacePlacementRanks(mod); placments.AddBorderPadding(borderPadding); return(placments); }