Exemple #1
0
        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);
        }