예제 #1
0
        static void Main(string[] args)
        {
            if (args.Contains("-OFast"))
            {
                Step = 10;
            }
            if (args.Contains("-OMax"))
            {
                Step = 1;
            }
            if (args.Contains("-debug"))
            {
                DrawAstar = true;
            }
            //string file = "test_D_O";
            string file = "test_D_O";
            //string file = "lut_00BB_D_O";
            //string file = "lut_00AB_D_O";

            if (args.Length > 0)
            {
                file = args[0];
            }

            var mainNetwork = new Mnet();
            mainNetwork.ReadMnetFile(file + @".MNET");

            //Удаление GNDS

            var gnds = mainNetwork.nodes.Where(t => t.NodeType == "GND" && !mainNetwork.wires.Any(t2=>t2.SrcName == t.NodeName)).ToList();
            foreach (var node in gnds)
            {
                var wires = mainNetwork.wires.Where(t => t.SrcName == node.NodeName).ToList();
                foreach (var wire in wires) mainNetwork.wires.Remove(wire);
                mainNetwork.nodes.Remove(node);
            }

            mainNetwork.wireGroups = new List<WireGroup>();

            //Перевести соеденения DUP в группы
            Console.WriteLine("Конвертирование DUP");
            var dupList = mainNetwork.nodes.Where(t => t.NodeType.Contains("DUP")).ToList();

            //Обьеденение DUP
            List<Node> list = dupList;
            var dupdupWires = mainNetwork.wires.Where(t => list.FirstOrDefault(a => a.NodeName == t.SrcName) != null &&
                                                           list.FirstOrDefault(a => a.NodeName == t.DistName) != null);
            while (dupdupWires.Any())

            {
                var wire = dupdupWires.First();
                var firstDup = dupList.First(a => a.NodeName == wire.SrcName);
                var secondDup = dupList.First(a => a.NodeName == wire.DistName);
                var fromSecondWires = mainNetwork.wires.Where(t => t.SrcName == secondDup.NodeName).ToList();
                foreach (var w in fromSecondWires)
                {
                    w.SrcName = firstDup.NodeName;
                }
                mainNetwork.wires.Remove(wire);
                mainNetwork.nodes.Remove(secondDup);
            }
            var orList = mainNetwork.nodes.Where(t => t.NodeType.Contains("OR")).ToList();
            dupList = mainNetwork.nodes.Where(t => t.NodeType.Contains("DUP")).ToList();

            //Обьеденение OR
            var opt = true;
            while (opt)
            {
                opt = false;
                var OrToOrWires = new List<Wire>();
                foreach (var node in orList)
                {
                    foreach (var node2 in orList)
                    {
                        OrToOrWires.AddRange(mainNetwork.wires.Where(t => t.SrcName == node.NodeName && node2.NodeName == t.DistName));
                    }
                }
                if (OrToOrWires.Count > 0)
                {
                    opt = true;
                    foreach (var wire in OrToOrWires)
                    {
                        var fromor = mainNetwork.nodes.First(t => t.NodeName == wire.SrcName);
                        var toor = mainNetwork.nodes.First(t => t.NodeName == wire.DistName);
                        var wires = new List<Wire>();
                        wires.AddRange(mainNetwork.wires.Where(t => t.DistName == fromor.NodeName));
                        wires.AddRange(mainNetwork.wires.Where(t => t.DistName == toor.NodeName));
                        wires.Remove(wire);
                        foreach (var w in wires)
                        {
                            w.DistName = wire.DistName;
                        }
                        mainNetwork.wires.Remove(wire);
                        mainNetwork.nodes.Remove(fromor);
                    }

                }
                else
                {

                }
            }
            //Создание Dummy обьектов
            //Поиск соеденений подходящих под DUMMY
            var dupToOrWires = new List<Wire>();
            foreach (var node in dupList)
            {
                foreach (var node2 in orList)
                {
                    dupToOrWires.AddRange(mainNetwork.wires.Where(t => t.SrcName == node.NodeName && node2.NodeName == t.DistName));
                }
            }
            //Поиск обратных связей
            foreach (var node in orList)
            {
                foreach (var node2 in dupList)
                {
                    dupToOrWires.AddRange(mainNetwork.wires.Where(t => t.SrcName == node.NodeName && node2.NodeName == t.DistName));
                }
            }

            //Создание DUMMY
            int dummynum = 0;
            foreach (var wire in dupToOrWires)
            {
                mainNetwork.nodes.Add(new Node { NodeName = "DUMMY_" + dummynum, NodeType = "DUMMY" });
                var newWire = new Wire { SrcName = "DUMMY_" + dummynum, SrcPort = "O0", DistName = wire.DistName, DistPort = wire.DistPort };
                wire.DistName = "DUMMY_" + dummynum;
                wire.DistPort = "I0";
                mainNetwork.wires.Add(newWire);
                dummynum++;
            }

            //Преобразование DUP В wireGroup
            dupList = mainNetwork.nodes.Where(t => t.NodeType.Contains("DUP")).ToList();

            var delinwirelist = new List<Wire>();
            var deloutwirelist = new List<Wire>();
            foreach (Node node in dupList)
            {
                string targetNodeName = node.NodeName;
                var inWires = mainNetwork.wires.Where(t => t.DistName == targetNodeName).ToList();
                var outWires = mainNetwork.wires.Where(t => t.SrcName == targetNodeName).ToList();
                foreach (var t in outWires)
                {
                    t.SrcName = inWires.First().SrcName;
                    t.SrcPort = inWires.First().SrcPort;
                }
                mainNetwork.wireGroups.Add(new WireGroup { GroupName = node.NodeName, WList = outWires,groupType = "DUP" });
                delinwirelist.AddRange(inWires);
                deloutwirelist.AddRange(outWires);
            }

            //Преобразование OR в WireGroup
            orList = mainNetwork.nodes.Where(t => t.NodeType.Contains("OR")).ToList();

            foreach (Node node in orList)
            {
                string targetNodeName = node.NodeName;
                var inWires = mainNetwork.wires.Where(t => t.DistName == targetNodeName).ToList();
                var outWires = mainNetwork.wires.Where(t => t.SrcName == targetNodeName).ToList();
                foreach (var t in inWires)
                {
                    t.DistName = outWires.First().DistName;
                    t.DistPort = outWires.First().DistPort;
                }
                mainNetwork.wireGroups.Add(new WireGroup { GroupName = node.NodeName, WList = inWires,groupType = "OR" });
                delinwirelist.AddRange(outWires);
                deloutwirelist.AddRange(inWires);
            }

            //Удаление соеденений

            foreach (var t in delinwirelist) mainNetwork.wires.Remove(t);
            foreach (var t in dupList) mainNetwork.nodes.Remove(t);
            foreach (var t in orList) mainNetwork.nodes.Remove(t);

            //loadnodes
            Console.WriteLine("Загрузка темплейтов");
            var mcNodes = new RouteUtils.Node[mainNetwork.nodes.Count];
            for (int i = 0; i < mainNetwork.nodes.Count; i++)
            {
                mcNodes[i] = new RouteUtils.Node(mainNetwork.nodes[i].NodeType + ".binhl")
                {
                    NodeName = mainNetwork.nodes[i].NodeName
                };
                mainNetwork.nodes[i].McNode = mcNodes[i];
            }
            Console.WriteLine("OK");
            //Place nodes
            int placeLayer;
            int baseSize;

            PlaceOptimal(mainNetwork, mcNodes, out placeLayer, out baseSize);

            //Удаление оставшихся соеденений
            foreach (var t in deloutwirelist) mainNetwork.wires.Remove(t);

            Console.WriteLine("Размещение ОК");

            var cpoints = new List<Cpoint>();

            //CreateCpointList

            for (int i = 0; i < mainNetwork.nodes.Count; i++)
            {
                cpoints.AddRange(mcNodes[i].InPorts.Select(t => new Cpoint
                {
                    BaseX = t.PosX + mainNetwork.nodes[i].X,
                    BaseY = t.PosY + mainNetwork.nodes[i].Y,
                    PointName = mainNetwork.nodes[i].NodeName + "-" + t.Name,
                    Indat = true
                }));

                cpoints.AddRange(mcNodes[i].OutPorts.Select(t => new Cpoint
                {
                    BaseX = t.PosX + mainNetwork.nodes[i].X,
                    BaseY = t.PosY + mainNetwork.nodes[i].Y,
                    PointName = mainNetwork.nodes[i].NodeName + "-" + t.Name,
                    Indat = false
                }));
            }

            SortWire(cpoints, mainNetwork, baseSize);

            var mcWires = new RouteUtils.Wire[mainNetwork.wires.Count];
            //Draw wires in layer
            int totalLayers = 0;
            for (int j = 0; j < 24; j++)
            {
                int currentWireLayer = j * 2 + 1;
                if (j > 4) currentWireLayer += 5;
                if (j > 9) currentWireLayer += 5;
                if (j > 14) currentWireLayer += 5;

                int currentRealLayer = placeLayer - 1 - j * 2;

                if (j > 4) currentRealLayer -= 2;
                if (j > 9) currentRealLayer -= 2;
                if (j > 14) currentRealLayer -= 2;

                int wireNum = 0;

                var wireMask = new char[baseSize, baseSize];

                //Разводка групп
                bool  canplace = true;
                while (canplace)
                {
                    //Разводка Группы

                    //Поиск лучшей группы для разводки
                    foreach (WireGroup group in mainNetwork.wireGroups)
                    {
                        if (!group.Placed)
                        {
                            group.weight = 0;
                            group.CanPlace = true;
                            foreach (Wire wire in group.WList)
                            {
                                //Поиск точек входа выхода
                                Cpoint startPoint = FindCpoint(wire.SrcName + "-" + wire.SrcPort, cpoints);
                                Cpoint endPoint = FindCpoint(wire.DistName + "-" + wire.DistPort, cpoints);

                                //Маскировка неиспользуемых точек;
                                foreach (Cpoint cpoint in cpoints)
                                {
                                    if (cpoint.UsedLayer == 0)
                                        DrawAtMask(wireMask, cpoint.BaseX, cpoint.BaseY + currentWireLayer, 1, 2);
                                }
                                //Отмена маскировки на конечных точках соеденения

                                startPoint.BaseY += currentWireLayer;
                                endPoint.BaseY += currentWireLayer;

                                UnmaskCpoint(wireMask, startPoint);
                                UnmaskCpoint(wireMask, endPoint);
                                var aStarTable = CalcAstar(baseSize, wireMask, startPoint, endPoint);

                                //CalcAstar

                                startPoint.BaseY -= currentWireLayer;
                                endPoint.BaseY -= currentWireLayer;
                                int weight = aStarTable[endPoint.BaseX, endPoint.BaseY + currentWireLayer];
                                if (weight == 0) group.CanPlace = false;
                                group.weight += weight;
                                wire.len = weight;
                                if (DrawAstar) RenderATable(wire + ".png", aStarTable, baseSize, startPoint, endPoint);

                            }
                        }
                    }

                    var bestGroup = mainNetwork.wireGroups.Where(q => q.CanPlace && !q.Placed).OrderBy(t => t.weight).FirstOrDefault();

                    //Разводка

                    if (bestGroup != null)
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("Разводка группы {0} из {1} соеденений", bestGroup.GroupName,bestGroup.WList.Count);
                        Console.ForegroundColor = ConsoleColor.White;
                        bestGroup.Placed = true;
                        bestGroup.WList = bestGroup.WList.OrderBy(t => t.len).ToList();
                        bestGroup.WList.Reverse();
                        foreach (Wire wire in bestGroup.WList)
                        {
                            Cpoint startPoint = FindCpoint(wire.SrcName + "-" + wire.SrcPort, cpoints);
                            Cpoint endPoint = FindCpoint(wire.DistName + "-" + wire.DistPort, cpoints);

                            if (bestGroup.groupType == "OR")
                            {
                                endPoint = FindCpoint(wire.SrcName + "-" + wire.SrcPort, cpoints);
                                startPoint = FindCpoint(wire.DistName + "-" + wire.DistPort, cpoints);
                            }

                            //Маскировка неиспользуемых точек;
                            foreach (Cpoint cpoint in cpoints)
                            {
                                if (cpoint.UsedLayer == 0)
                                    DrawAtMask(wireMask, cpoint.BaseX, cpoint.BaseY + currentWireLayer, 1, 2);
                            }
                            //Отмена маскировки на конечных точках соеденения

                            startPoint.BaseY += currentWireLayer;
                            endPoint.BaseY += currentWireLayer;

                            UnmaskCpoint(wireMask, startPoint);
                            UnmaskCpoint(wireMask, endPoint);

                            var aStarTable = CalcAstar(baseSize, wireMask, startPoint, endPoint);
                            MultiWareAstarUpdate(aStarTable, bestGroup);

                            List<int> wpx;
                            List<int> wpy;

                            bool placed = TryPlaceWire(startPoint, endPoint, aStarTable, out wpx, out wpy);
                            if (placed)
                            {
                                //WireRemask
                                wire.WirePoints = new List<WirePoint>();
                                for (int i = 0; i < wpx.Count; i++)
                                {
                                    wire.WirePoints.Add(new WirePoint { x = wpx[i], y = wpy[i], z = currentRealLayer });
                                }
                                wire.WirePoints.Reverse();

                                startPoint.UsedLayer = currentWireLayer;
                                endPoint.UsedLayer = currentWireLayer;
                                wire.Placed = true;
                            }

                            //startPoint.BaseY -= 1;
                            //endPoint.BaseY -= 1;
                            startPoint.BaseY -= currentWireLayer;
                            endPoint.BaseY -= currentWireLayer;
                            wireNum++;
                            //RenderATable(wire + ".png", aStarTable, baseSize, startPoint, endPoint);
                        }

                        foreach (Wire wire in bestGroup.WList)
                        {
                            foreach (var point in wire.WirePoints)
                            {
                                DrawAtMask(wireMask, point.x, point.y, 1, 1);
                            }
                            if (bestGroup.groupType == "OR")
                            {
                                wire.WirePoints.Reverse();
                            }
                        }
                    }
                    else
                    {
                        canplace = false;
                    }
                }

                //Разводка Соеденений

                for (int i = 0; i < mainNetwork.wires.Count; i++)
                {
                    int mink = 999999;
                    int bestN = 0;

                    for (int k = 0; k < mainNetwork.wires.Count; k++)
                    {
                        if (!mainNetwork.wires[k].Placed)
                        {
                            int bw = FindBestWireToRoute(mainNetwork, baseSize, cpoints, currentWireLayer, currentRealLayer, k, mcWires, wireMask);
                            if (mink > bw && bw != 0)
                            {
                                mink = bw;
                                bestN = k;
                            }
                        }
                    }
                    if (!mainNetwork.wires[bestN].Placed)
                    {
                        List<int> wpx;
                        List<int> wpy;
                        PlaceWire(mainNetwork, baseSize, cpoints, currentWireLayer, currentRealLayer, bestN, mcWires, wireMask, out wpx, out wpy);
                        if (mainNetwork.wires[bestN].Placed)
                        {
                            Console.ForegroundColor = ConsoleColor.Green;
                            wireNum++;
                            Console.WriteLine(mainNetwork.wires[bestN].ToString());
                        }
                        else
                        {
                            i = mainNetwork.wires.Count;
                            Console.ForegroundColor = ConsoleColor.White;
                        }

                    }
                    else
                    {
                        i = mainNetwork.wires.Count;
                    }
                }
                Console.WriteLine("Разведено в текущем слое:" + wireNum);
                if (wireNum > 0)
                {
                    totalLayers++;
                }
                else
                {
                    break;
                }
            }
            Console.WriteLine("Всего Слоев:" + totalLayers);

            var outNode = new RouteUtils.Node("OUT", baseSize, baseSize, placeLayer + 10);

            //OutNode.PlaceAnotherNode(new RouteUtils.Node("DUP23.binhl"), 0, 0, 0);
            for (int i = 0; i < mainNetwork.nodes.Count; i++)
            {
                outNode.PlaceAnotherNode(mcNodes[i], mainNetwork.nodes[i].X, mainNetwork.nodes[i].Y, mainNetwork.nodes[i].Z);

            }
            //LongCpoint

            foreach (Cpoint cpoint in cpoints)
            {
                if (cpoint.UsedLayer >= 10)
                {
                    cpoint.UsedLayer -= 4;
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 12, placeLayer - 11] = "W";
                    if (cpoint.Indat)
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 12, placeLayer - 10] = "^";
                    else
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 12, placeLayer - 10] = "v";

                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 13, placeLayer - 11] = "W";
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 13, placeLayer - 10] = "#";
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 14, placeLayer - 11] = "W";
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 14, placeLayer - 10] = "#";
                }

                if (cpoint.UsedLayer >= 22)
                {
                    cpoint.UsedLayer -= 3;
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 27, placeLayer - 23] = "W";
                    if (cpoint.Indat)
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 27, placeLayer - 22] = "^";
                    else
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 27, placeLayer - 22] = "v";

                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 28, placeLayer - 23] = "W";
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 28, placeLayer - 22] = "#";
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 29, placeLayer - 23] = "W";
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 29, placeLayer - 22] = "#";
                }

                if (cpoint.UsedLayer >= 34)
                {
                    cpoint.UsedLayer -= 3;
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 42, placeLayer - 35] = "W";
                    if (cpoint.Indat)
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 42, placeLayer - 34] = "^";
                    else
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 42, placeLayer - 34] = "v";

                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 43, placeLayer - 35] = "W";
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 43, placeLayer - 34] = "#";
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 44, placeLayer - 35] = "W";
                    outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + 44, placeLayer - 34] = "#";
                }

                for (int j = 0; j < cpoint.UsedLayer; j++)
                {
                    if (j <= 10)
                    {
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + j + 1, placeLayer - j - 1] = "w";
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + j + 1, placeLayer - j - 0] = "#";
                    }
                    if (j > 10 && j <= 22)
                    {
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + j + 4, placeLayer - j - 1] = "w";
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + j + 4, placeLayer - j - 0] = "#";
                    }
                    if (j > 22 && j <= 34)
                    {
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + j + 7, placeLayer - j - 1] = "w";
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + j + 7, placeLayer - j - 0] = "#";
                    }

                    if (j > 34)
                    {
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + j + 10, placeLayer - j - 1] = "w";
                        outNode.DataMatrix[cpoint.BaseX, cpoint.BaseY + j + 10, placeLayer - j - 0] = "#";
                    }
                }
            }
            //PlaceReapiters
            for (int i = 0; i < mainNetwork.wires.Count; i++)
            {
                mcWires[i].PlaceRepeaters();
            }

            //Установка репитеров для групп
            foreach (var group in mainNetwork.wireGroups)
            {
                group.PlaceRepitors();
            }
            //Установка групп соеденений

            //SyncWires
            var wiresToSync = new List<RouteUtils.Wire>();
            for (int i = 0; i < mainNetwork.wires.Count; i++)
            {
                if (mainNetwork.wires[i].DistPort == "clk")
                {
                    wiresToSync.Add(mcWires[i]);
                }
            }
            int syncLen = wiresToSync.Select(t => t.CalcRepCount()).Concat(new[] {0}).Max();

            foreach (RouteUtils.Wire wire in wiresToSync)
            {
                wire.RepCompincate(syncLen - wire.CalcRepCount());
                wire.Synced = true;
            }

            foreach (var group in mainNetwork.wireGroups)
            {
                foreach (var wire in group.WList)
                {
                    foreach (var point in wire.WirePoints)
                    {
                        outNode.DataMatrix[point.x, point.y, point.z] = "S";
                        if (wire.repError)
                            outNode.DataMatrix[point.x, point.y, point.z] = "W";

                        outNode.DataMatrix[point.x, point.y, point.z + 1] = "#";
                        if (point.Repiter)
                            outNode.DataMatrix[point.x, point.y, point.z + 1] = point.RepVapl;
                    }
                }
            }
            //отрисовка ошибочного соеденения
            foreach (var group in mainNetwork.wireGroups)
            {
                foreach (var wire in group.WList)
                {
                    if (wire.repError)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine(wire);
                        Console.ForegroundColor = ConsoleColor.White;
                        foreach (var point in wire.WirePoints)
                        {
                            outNode.DataMatrix[point.x, point.y, point.z] = "S";
                            if (wire.repError)
                                outNode.DataMatrix[point.x, point.y, point.z] = "W";

                            outNode.DataMatrix[point.x, point.y, point.z + 1] = "#";
                            if (point.Repiter)
                                outNode.DataMatrix[point.x, point.y, point.z + 1] = point.RepVapl;
                        }
                    }
                }
            }

            //PlaceWires
            for (int i = 0; i < mainNetwork.wires.Count; i++)
            {
                if (mainNetwork.wires[i].Placed)
                {
                    for (int j = 0; j < mcWires[i].WirePointX.Length; j++)
                    {
                        if (mcWires[i].Synced)
                        {
                            outNode.DataMatrix[mcWires[i].WirePointX[j], mcWires[i].WirePointY[j], mcWires[i].WirePointZ[j]] = "S";
                        }
                        else
                        {
                            outNode.DataMatrix[mcWires[i].WirePointX[j], mcWires[i].WirePointY[j], mcWires[i].WirePointZ[j]] = "w";
                        }
                        if (mcWires[i].Rep[j])
                        {
                            outNode.DataMatrix[mcWires[i].WirePointX[j], mcWires[i].WirePointY[j], mcWires[i].WirePointZ[j] + 1] = mcWires[i].RepNp[j];
                        }
                        else
                        {
                            outNode.DataMatrix[mcWires[i].WirePointX[j], mcWires[i].WirePointY[j], mcWires[i].WirePointZ[j] + 1] = "#";
                        }
                    }
                }
            }

            //Обрезка
            Console.WriteLine("Обрезка рабочей Облости");
            var outNodeO = CutOutputNode(placeLayer, baseSize, outNode);
            //Маркировка портов ввода вывода
            outNodeO.InPorts = mainNetwork.nodes.Where(t => t.NodeType == "INPort").Select(t => new InPort(t.NodeName, t.X + 1, t.Y)).ToArray();
            outNodeO.OutPorts = mainNetwork.nodes.Where(t => t.NodeType == "OUTPort").Select(t => new OutPort(t.NodeName, t.X + 1, t.Y)).ToArray();

            Console.WriteLine("Экспорт");
            outNodeO.Export(file + ".binhl");
        }
예제 #2
0
 private static int CalcPortNum(Mnet MainNetwork)
 {
     int PortNum = 0;
     for (int i = 0; i < MainNetwork.nodes.Count; i++)
     {
         if (MainNetwork.nodes[i].NodeType.Contains("Port"))
         {
             PortNum++;
         }
     }
     return PortNum;
 }
예제 #3
0
        private static bool TryPlace(Mnet MainNetwork, RouteUtils.Node[] mcNodes, int PlaceLayer, int BaseSize)
        {
            char[,] PlaceMask = new char[BaseSize, BaseSize];

            //PlacePorts
            int potrtx = 1;
            for (int i = 0; i < MainNetwork.nodes.Count; i++)
            {
                if (MainNetwork.nodes[i].NodeType.Contains("Port"))
                {
                    MainNetwork.nodes[i].X = potrtx;
                    MainNetwork.nodes[i].Y = 1;
                    MainNetwork.nodes[i].Z = PlaceLayer;
                    //DrawMask
                    int mx = MainNetwork.nodes[i].X;
                    int my = MainNetwork.nodes[i].Y;
                    int mw = mcNodes[i].SizeX;
                    int mh = mcNodes[i].SizeY;

                    DrawAtMask(PlaceMask, mx, my, mw, mh + 3);

                    potrtx += 4;
                }
            }

            int lastY = 1;
            int lastX = 1;
            for (int i = 0; i < MainNetwork.nodes.Count; i++)
            {
                bool placed = false;
                if (MainNetwork.nodes[i].NodeType.Contains("Port"))
                {
                    placed = true;
                }

                for (int x = lastX; x < BaseSize; x += Dolled)
                {
                    for (int y = 1; y < BaseSize; y += Dolled)
                    {
                        if (!placed)
                        {
                            MainNetwork.nodes[i].X = x;
                            MainNetwork.nodes[i].Y = y;
                            MainNetwork.nodes[i].Z = PlaceLayer;

                            int mx = MainNetwork.nodes[i].X;
                            int my = MainNetwork.nodes[i].Y;
                            int mw = mcNodes[i].SizeX;
                            int mh = mcNodes[i].SizeY;

                            if (CanPlace(PlaceMask, mx, my, mw, mh + 3))
                            {
                                DrawAtMask(PlaceMask, mx, my, mw, mh + 3);
                                placed = true;
                                lastX = x;
                                lastY = y;
                            }
                        }
                    }
                }

                if (!placed)
                    return false;
            }
            return true;
        }
예제 #4
0
        private static int FindBestWireToRoute(Mnet MainNetwork, int BaseSize, List<RouteUtils.Cpoint> Cpoints, int CurrentWireLayer, int CurrentRealLayer, int WireNum, RouteUtils.Wire[] MCWires, char[,] wireMask)
        {
            for (int j = 0; j < Cpoints.Count; j++)
            {
                if (Cpoints[j].UsedLayer == 0)
                    DrawAtMask(wireMask, Cpoints[j].BaseX, Cpoints[j].BaseY + CurrentWireLayer, 1, 2);
            }

            Wire W = MainNetwork.wires[WireNum];

            RouteUtils.Wire MCW = new RouteUtils.Wire(W.SrcName + "-" + W.SrcPort, W.DistName + "-" + W.DistPort);
            //UnmaskStartEndPoint
            RouteUtils.Cpoint SP = FindCpoint(MCW.StartName, Cpoints);
            RouteUtils.Cpoint EP = FindCpoint(MCW.EndName, Cpoints);

            SP.BaseY += CurrentWireLayer;
            EP.BaseY += CurrentWireLayer;

            UnmaskCpoint(wireMask, SP);
            UnmaskCpoint(wireMask, EP);
            //CalcAstar
            int[,] AStarTable = CalcAstar(BaseSize, wireMask, SP, EP);
            SP.BaseY -= CurrentWireLayer;
            EP.BaseY -= CurrentWireLayer;

            return AStarTable[EP.BaseX, EP.BaseY + CurrentWireLayer];
        }
예제 #5
0
 private static void SortOptimize(Mnet MainNetwork)
 {
     for (int i = 0; i < MainNetwork.nodes.Count * OptimiseDeep; i++)
     {
         for (int j = 2; j < (MainNetwork.nodes.Count - 1); j++)
         {
             if (MainNetwork.nodes[j].NodeType != "INPort" && MainNetwork.nodes[j].NodeType != "OUTPort")
             {
                 List<Wire> Wlist1 = FindAllWiresTo(MainNetwork.wires, MainNetwork.nodes[j]);
                 //List<Wire> Wlist2 = FindAllWiresTo(MainNetwork.wires, MainNetwork.nodes[j+1]);
                 int ka = 0;
                 if (TypeSort)
                 {
                     int wa = CalcTypeWeight(MainNetwork.nodes[j]);
                     int wb = CalcTypeWeight(MainNetwork.nodes[j - 1]);
                     if (wa > wb)
                     {
                         ka = 1;
                     }
                     else
                     {
                         ka = 0;
                     }
                 }
                 else
                 {
                     ka = CalcWireLens(Wlist1, MainNetwork);
                 }
                 //int kb = CalcWireLens(Wlist2, MainNetwork);
                 if (ka < 0)
                 {
                     if (MainNetwork.nodes[j + 1].NodeType != "INPort" && MainNetwork.nodes[j + 1].NodeType != "OUTPort")
                     {
                         Node N = new Node();
                         N = MainNetwork.nodes[j];
                         MainNetwork.nodes[j] = MainNetwork.nodes[j + 1];
                         MainNetwork.nodes[j + 1] = N;
                     }
                 }
                 if (ka > 0)
                 {
                     if (MainNetwork.nodes[j - 1].NodeType != "INPort" && MainNetwork.nodes[j - 1].NodeType != "OUTPort")
                     {
                         Node N = new Node();
                         N = MainNetwork.nodes[j];
                         MainNetwork.nodes[j] = MainNetwork.nodes[j - 1];
                         MainNetwork.nodes[j - 1] = N;
                     }
                 }
             }
         }
     }
 }
예제 #6
0
        private static void SortWire(List<RouteUtils.Cpoint> Cpoints, Mnet MainNetwork, int BW)
        {
            int Moves = 1;
            while (Moves > 0)
                Moves = 0;
            for (int i = 1; i < MainNetwork.wires.Count; i++)
            {
                RouteUtils.Cpoint CA = FindCpoint(MainNetwork.wires[i].SrcName + "-" + MainNetwork.wires[i].SrcPort, Cpoints);
                RouteUtils.Cpoint CB = FindCpoint(MainNetwork.wires[i - 1].SrcName + "-" + MainNetwork.wires[i - 1].SrcPort, Cpoints);
                int ka = CA.BaseX + CA.BaseY * BW;
                int kb = CB.BaseX + CB.BaseY * BW;
                if (ka < kb)
                {
                    Wire W = MainNetwork.wires[i];
                    MainNetwork.wires[i] = MainNetwork.wires[i - 1];
                    MainNetwork.wires[i - 1] = W;
                }

            }
        }
예제 #7
0
 private static void RemoveDUOWires(Mnet MainNetwork, List<Node> Nodes)
 {
     for (int i = 0; i < Nodes.Count; i++)
     {
         for (int j = 0; i < Nodes.Count; i++)
         {
             MainNetwork.RemoveWireTo(Nodes[i].NodeName, "I" + j.ToString());
         }
     }
 }
예제 #8
0
 private static void RemoveDUPNodes(Mnet MainNetwork, List<Node> Nodes)
 {
     for (int i = 0; i < MainNetwork.nodes.Count; i++)
     {
         if (MainNetwork.nodes[i].NodeType.StartsWith("DUP"))
         {
             Nodes.Add(MainNetwork.nodes[i]);
         }
     }
     for (int i = 0; i < Nodes.Count; i++)
     {
         MainNetwork.RemoveNode(Nodes[i].NodeName);
     }
 }
예제 #9
0
        private static void ReducteDUP(Mnet MainNetwork)
        {
            List<Node> Nodes = new List<Node>();
            for (int i = 0; i < MainNetwork.nodes.Count; i++)
            {
                if (MainNetwork.nodes[i].NodeType.StartsWith("DUP"))
                {
                    Nodes.Add(MainNetwork.nodes[i]);
                }
            }
            // DupUnion

            List<string> Dnodes = new List<string>();
            List<string> Snodes = new List<string>();
            for (int i = 0; i < MainNetwork.wires.Count; i++)
            {
                if (MainNetwork.FindNode(MainNetwork.wires[i].DistName).NodeType.StartsWith("DUP"))
                {
                    if (MainNetwork.FindNode(MainNetwork.wires[i].SrcName).NodeType.StartsWith("DUP"))
                    {
                        while (MainNetwork.FindWireFrom(MainNetwork.wires[i].DistName) != null)
                        {
                            Wire W = MainNetwork.FindWireFrom(MainNetwork.wires[i].DistName);
                            W.SrcName = MainNetwork.wires[i].SrcName;
                        }
                        Dnodes.Add(MainNetwork.wires[i].DistName);
                        Dnodes.Add(MainNetwork.wires[i].SrcName);
                    }
                }
            }
        }
예제 #10
0
 private static int CalcWireLens(List<Wire> WlistTo, Mnet MainNetwork)
 {
     int k = 0;
     for (int i = 0; i < WlistTo.Count; i++)
     {
         int ka = FindNodeIndex(MainNetwork.nodes, WlistTo[i].SrcName);
         int kb = FindNodeIndex(MainNetwork.nodes, WlistTo[i].DistName);
         k += (kb - ka);
     }
     return k;
 }
예제 #11
0
        private static void PlaceWire(Mnet MainNetwork, int BaseSize, List<RouteUtils.Cpoint> Cpoints, int CurrentWireLayer, int CurrentRealLayer, int WireNum, RouteUtils.Wire[] MCWires, char[,] wireMask, out List<int> WPX, out List<int> WPY)
        {
            //wireMask = new string[BaseSize, BaseSize];

            //PlaceMaskCpoint
            for (int j = 0; j < Cpoints.Count; j++)
            {
                if (Cpoints[j].UsedLayer == 0)
                    DrawAtMask(wireMask, Cpoints[j].BaseX, Cpoints[j].BaseY + CurrentWireLayer, 1, 2);
            }

            Wire W = MainNetwork.wires[WireNum];

            RouteUtils.Wire MCW = new RouteUtils.Wire(W.SrcName + "-" + W.SrcPort, W.DistName + "-" + W.DistPort);
            //UnmaskStartEndPoint
            RouteUtils.Cpoint SP = FindCpoint(MCW.StartName, Cpoints);
            RouteUtils.Cpoint EP = FindCpoint(MCW.EndName, Cpoints);

            SP.BaseY += CurrentWireLayer;
            EP.BaseY += CurrentWireLayer;

            UnmaskCpoint(wireMask, SP);
            UnmaskCpoint(wireMask, EP);
            //CalcAstar
            int[,] AStarTable = CalcAstar(BaseSize, wireMask, SP, EP);

            //DrawWire

            bool placed = TryPlaceWire(SP, EP, AStarTable, out WPX, out WPY);
            if (placed)
            {
                //WireRemask
                for (int i = 0; i < WPX.Count; i++)
                {
                    DrawAtMask(wireMask, WPX[i], WPY[i], 1, 1);
                }

                MCWires[WireNum] = new RouteUtils.Wire(MCW.StartName, MCW.EndName);

                MCWires[WireNum].WirePointX = new int[WPX.Count];
                MCWires[WireNum].WirePointY = new int[WPX.Count];
                MCWires[WireNum].WirePointZ = new int[WPX.Count];

                for (int i = 0; i < WPX.Count; i++)
                {
                    MCWires[WireNum].WirePointX[WPX.Count - i - 1] = WPX[i];
                    MCWires[WireNum].WirePointY[WPX.Count - i - 1] = WPY[i];
                    MCWires[WireNum].WirePointZ[WPX.Count - i - 1] = CurrentRealLayer;
                }
                MainNetwork.wires[WireNum].Placed = true;

                SP.UsedLayer = CurrentWireLayer;
                EP.UsedLayer = CurrentWireLayer;
            }
            SP.BaseY -= CurrentWireLayer;
            EP.BaseY -= CurrentWireLayer;
        }
예제 #12
0
        private static void PlaceOptimal(Mnet mainNetwork, RouteUtils.Node[] mcNodes, out int PlaceLayer, out int BaseSize)
        {
            //Расчитать baseSize
            PlaceLayer = 60;
            int xStep = mcNodes.Select(t => t.SizeX).Max() + Dolled;
            int yStep = mcNodes.Select(t => t.SizeY).Max() + Dolled;

            BaseSize = (new int[] { Convert.ToInt32(Math.Sqrt(mcNodes.Length)) * xStep, Convert.ToInt32(Math.Sqrt(mcNodes.Length)) * yStep }).Max() + 60;

            //Разместить порты
            var ports = mainNetwork.nodes.Where(t => t.NodeType.Contains("Port"));
            if (BaseSize < ports.Count() * 5)
            {
                BaseSize = ports.Count()*5 + 60;
            }
            int lastxcoord = 1;
            foreach (var port in ports)
            {
                port.Placed = true;
                port.X = lastxcoord;
                port.Y = 1;
                port.Z = PlaceLayer;
                lastxcoord += mcNodes.FirstOrDefault(t => t.NodeName == port.NodeName).SizeX + Dolled;
            }
            //Расчитать матрицу связоности
            int[,] connectionMatrix = new int[mainNetwork.nodes.Count, mainNetwork.nodes.Count];
            for (int i = 0; i < mainNetwork.nodes.Count; i++)
            {
                for (int j = 0; j < mainNetwork.nodes.Count; j++)
                {
                    connectionMatrix[i, j] = mainNetwork.wires.Where(t => t.SrcName == mainNetwork.nodes[i].NodeName && t.DistName == mainNetwork.nodes[j].NodeName ||
                                                                          t.SrcName == mainNetwork.nodes[j].NodeName && t.DistName == mainNetwork.nodes[i].NodeName).Count();
                }
            }

            //Разместить ноды в ячейки
            var unPlaced = mainNetwork.nodes.Where(t => !t.Placed);
            while (unPlaced.Count() > 0)
            {
                //Поиск нода максимально связанного с установленными
                int[] localConnectionMatrix = new int[mainNetwork.nodes.Count];
                for (int i = 0; i < mainNetwork.nodes.Count; i++)
                {
                    localConnectionMatrix[i] += mainNetwork.wires.Where(t => !mainNetwork.nodes[i].Placed &&
                                                                             (t.SrcName == mainNetwork.nodes[i].NodeName && mainNetwork.nodes.FirstOrDefault(n => n.NodeName == t.DistName).Placed)).Count();
                    localConnectionMatrix[i] += mainNetwork.wires.Where(t => !mainNetwork.nodes[i].Placed &&
                                                                             (t.DistName == mainNetwork.nodes[i].NodeName && mainNetwork.nodes.FirstOrDefault(n => n.NodeName == t.SrcName).Placed)).Count();
                }
                int maxConections = localConnectionMatrix.Max();
                Node nodeToPlace = new Node();
                for (int i = 0; i < mainNetwork.nodes.Count; i++)
                {
                    if (localConnectionMatrix[i] == maxConections)
                    {
                        nodeToPlace = mainNetwork.nodes[i];
                    }
                }
                if (maxConections == 0)
                {
                    nodeToPlace = unPlaced.FirstOrDefault();
                }
                //Поиск места для установки
                int[,] placeMatrix = new int[BaseSize, BaseSize];
                var connectionsa = mainNetwork.wires.Where(k => k.SrcName == nodeToPlace.NodeName).Select(s => mainNetwork.nodes.FirstOrDefault(q => s.DistName == q.NodeName)).Where(l => l.Placed);
                var connectionsb = mainNetwork.wires.Where(k => k.DistName == nodeToPlace.NodeName).Select(s => mainNetwork.nodes.FirstOrDefault(q => s.SrcName == q.NodeName)).Where(l => l.Placed);
                var connections = connectionsa.Union(connectionsb);
                var mcNode = mcNodes.FirstOrDefault(k => k.NodeName == nodeToPlace.NodeName);
                int sizex = mcNode.SizeX + Dolled;
                int sizey = mcNode.SizeY + Dolled;
                var placedNodes = mainNetwork.nodes.Where(t => t.Placed);

                char[,] mask = new char[BaseSize, BaseSize];
                foreach (var node in placedNodes)
                {
                    DrawAtMask(mask, node.X, node.Y, node.McNode.SizeX + 3, node.McNode.SizeY);//При Более близко расположении бывают ошибки
                }

                for (int i = 0; i < BaseSize; i += Step)
                {
                    for (int j = 0; j < BaseSize; j += Step)
                    {
                        //bool collision = placedNodes.Where(t => CheckCollision(t, t.mcNode, i, j, mcNode)).Count() > 0;
                        if (BaseSize > i + sizex + 1 && BaseSize > j + sizey + 1)
                            if (!CheckMaskCollision(mask, nodeToPlace, i, j))
                            {
                                foreach (Node n in connections)
                                {
                                    placeMatrix[i, j] += (n.X - i) * (n.X - i) + (n.Y - j) * (n.Y - j);
                                }
                            }
                    }
                }
                //Установка
                int pcondMin = 90000000;
                int xplace = 0;
                int yplace = 0;
                for (int i = 1; i < BaseSize; i++)
                {
                    for (int j = 1; j < BaseSize; j++)
                    {
                        if (placeMatrix[i, j] < pcondMin && placeMatrix[i, j] > 0)
                        {
                            xplace = i;
                            yplace = j;
                            pcondMin = placeMatrix[i, j];
                        }
                    }
                }
                nodeToPlace.X = xplace;
                nodeToPlace.Y = yplace;
                nodeToPlace.Z = PlaceLayer;
                nodeToPlace.Placed = true;
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine("{0} - Осталось:{1}", nodeToPlace.NodeName, unPlaced.Count());
                Console.ForegroundColor = ConsoleColor.White;
            }
            //foreach(Node node in )

            BaseSize += PlaceLayer;
            //Debug Draw Image
            System.Drawing.Image im = new System.Drawing.Bitmap(BaseSize, BaseSize);
            System.Drawing.Graphics Gr = System.Drawing.Graphics.FromImage(im);
            Gr.Clear(System.Drawing.Color.Black);
            foreach (var node in mainNetwork.nodes)
            {
                Gr.DrawRectangle(System.Drawing.Pens.Green, node.X, node.Y, node.McNode.SizeX, node.McNode.SizeY);
            }
            im.Save("1.png");

            //Увеличить плотность
            //throw new NotImplementedException();
        }
예제 #13
0
        private static void PlaceCompact(Mnet MainNetwork, RouteUtils.Node[] mcNodes, out int PlaceLayer, out int BaseSize)
        {
            PlaceLayer = 60;
            int PortNum = CalcPortNum(MainNetwork);

            BaseSize = 5 * PortNum;

            while (!TryPlace(MainNetwork, mcNodes, PlaceLayer, BaseSize))
            {
                BaseSize += 10;
                Console.WriteLine("Размер:" + BaseSize.ToString());
            }
            BaseSize += PlaceLayer;
        }