/// <summary>
        /// The FPGA is already read in, this time only read wire statements
        /// </summary>
        /// <param name="line"></param>
        /// <param name="sr"></param>
        public void ParseWire(Tile tile, XDLStreamReaderWithUndo sr, UnresolvedWires unresWires)
        {
            WireList wireList = new WireList();

            string line = "";

            while ((line = sr.ReadLine()) != null)
            {
                if (line.Contains("(wire"))
                {
                    wireList = XDLWireParser.Parse(tile, sr, unresWires);
                }
                else if (line.Contains("tile_summary") && unresWires == null)
                {
                    StoreAndShareWireList(tile, wireList);

                    //consume closing bracket and exit
                    line = sr.ReadLine();

                    return;
                }
                else if (line.Contains("tile_summary") && unresWires != null)
                {
                    //consume closing bracket and exit
                    line = sr.ReadLine();

                    return;
                }
            }
        }
Beispiel #2
0
        //private static Regex m_closingBrackes = new Regex(@"^\s+\)", RegexOptions.Compiled);
        //private static Regex m_summary = new Regex("(pip)|(tile_summary)", RegexOptions.Compiled);

        public static WireList Parse(Tile containingTile, XDLStreamReaderWithUndo sr, UnresolvedWires unresWires)
        {
            WireList wires = new WireList();

            sr.UndoLastRead();

            while (true)
            {
                //          (wire WS5BEG1 3
                //	            (conn INT_BUFS_R_X18Y78 INT_BUFS_WS5B1)
                //	            (conn INT_X18Y78 WS5A1)
                //	            (conn CLBLM_X18Y78 CLB_WS5A1)
                //          )

                string line = sr.ReadLine();
                bool   conn = line.Contains("(conn");
                if (!conn)
                {
                    if (line.Contains("pip") || line.Contains("tile_summary"))
                    {
                        sr.UndoLastRead();
                        break;
                    }
                }

                // skip closing brackets
                //if (WireParser.m_closingBrackes.IsMatch(nextLine))
                if (line.EndsWith(")"))
                {
                    continue;
                }

                int firstBracketWire = line.IndexOf('(', 0);
                int firstBlankWire   = line.IndexOf(' ', firstBracketWire);
                int secondBlankWire  = line.IndexOf(' ', firstBlankWire + 1);

                // e.g. (wire WS5BEG1 3
                // wireName becomes WS5BEG1
                string wireName = line.Substring(firstBlankWire + 1, secondBlankWire - firstBlankWire - 1);
                // wireCount becomes 3
                string wireCountStr = line.Substring(secondBlankWire + 1, line.Length - secondBlankWire - 1);
                int    wireCount    = int.Parse(wireCountStr);

                // wire classification
                bool beginPip = false;
                bool endPip   = false;

                beginPip = containingTile.SwitchMatrix.ContainsRight(new Port(wireName));

                // HasArcs is expensive, only search if the the pip is a not begin pip
                if (!beginPip)
                {
                    endPip = containingTile.SwitchMatrix.ContainsLeft(new Port(wireName));
                }

                for (int i = 0; i < wireCount; i++)
                {
                    line = sr.ReadLine();

                    if (beginPip || endPip)
                    {
                        Tile targetTile;
                        Wire w = GetWire(line, containingTile, wireName, beginPip, false, unresWires, out targetTile);
                        if (w == null)
                        {
                            continue;
                        }

                        bool destinationExists = Navigator.DestinationAndWireExists(containingTile, w);
                        if (destinationExists && unresWires == null)
                        {
                            // regular wire (bipartite case: wire, pip, wire, pip)
                            wires.Add(w);
                        }
                        else if (!destinationExists && unresWires != null)
                        {
                            // store wire for later
                            unresWires.Add(containingTile, w);
                        }
                    }
                    else if (unresWires != null)
                    {
                        Tile targetTile;
                        Wire w = GetWire(line, containingTile, wireName, beginPip, true, unresWires, out targetTile);
                        if (w == null)
                        {
                            continue;
                        }

                        // store wire for later
                        unresWires.Add(containingTile, w);
                    }
                }
            }

            return(wires);
        }
Beispiel #3
0
        private void ResolveWires(UnresolvedWires unresWires)
        {
            Watch.Start("ResolveWires");
            if (unresWires == null)
            {
                return;
            }

            List <Tuple <Tile, WireList> > updates = new List <Tuple <Tile, WireList> >();

            foreach (Tuple <Tile, WireList> tuple in unresWires.Where(t => t.Item1.SwitchMatrix.ArcCount != 0))
            {
                //Console.WriteLine(tuple.Item1.Location + " with " + tuple.Item2.Count);
                WireList wiresToNonExistingTiles = new WireList();
                foreach (Wire srcWire in tuple.Item2)
                {
                    Watch.Start("GetDestinationByWire 1");
                    Tile destTile = Navigator.GetDestinationByWire(tuple.Item1, srcWire);
                    Watch.Stop("GetDestinationByWire 1");

                    Watch.Start("contains");
                    bool contains = unresWires.Contains(destTile.TileKey.X, destTile.TileKey.Y);
                    Watch.Stop("contains");
                    if (!contains || !tuple.Item1.SwitchMatrix.Contains(new Port(srcWire.LocalPip)))
                    {
                        wiresToNonExistingTiles.Add(srcWire, false);
                        continue;
                    }

                    WireList dstWireList = unresWires.Get(destTile);
                    Watch.Start("inner loop");
                    foreach (Wire dstWire in dstWireList.Where(d => d.LocalPipKey.Equals(srcWire.PipOnOtherTileKey) && !d.PipOnOtherTile.Equals(srcWire.LocalPip)))
                    {
                        Watch.Start("GetDestinationByWire 2");
                        Tile otherTile = Navigator.GetDestinationByWire(destTile, dstWire);
                        Watch.Stop("GetDestinationByWire 2");

                        // tile a -> wire -> tile b -> wire -> tile a , but tile b has no switch matrix. only add wires to tiles with non empty switch matrices
                        // as otherwise the wire can not used
                        Watch.Start("Match");
                        bool match = otherTile.Location.Equals(tuple.Item1.Location) &&
                                     //!dstWire.PipOnOtherTile.Equals(srcWire.LocalPip) &&
                                     //tuple.Item1.SwitchMatrix.ArcCount > 0 &&
                                     //tuple.Item1.SwitchMatrix.Contains(new Port(srcWire.LocalPip)) &&
                                     tuple.Item1.SwitchMatrix.Contains(new Port(dstWire.PipOnOtherTile));
                        Watch.Stop("Match");

                        if (match)
                        {
                            //this.OutputManager.WriteOutput
                            //Console.WriteLine("Add loop wire on " + tuple.Item1.Location + " connecting " + srcWire.LocalPip + " with " + dstWire.PipOnOtherTile + " (via " + destTile.Location + ")");
                            Watch.Start("Parse");
                            Wire w = new Wire(srcWire.LocalPipKey, dstWire.PipOnOtherTileKey, true, 0, 0);
                            Watch.Stop("Parse");

                            // no duplicates
                            Watch.Start("HasWire");
                            if (!tuple.Item1.WireList.HasWire(w))
                            {
                                tuple.Item1.WireList.Add(w, false);
                                m_loopWires++;
                            }
                            Watch.Stop("HasWire");
                        }
                    }
                    Watch.Stop("inner loop");
                }

                if (wiresToNonExistingTiles.Count < tuple.Item2.Count)
                {
                    updates.Add(new Tuple <Tile, WireList>(tuple.Item1, wiresToNonExistingTiles));
                }
            }

            Watch.Start("Clean");
            foreach (Tuple <Tile, WireList> tuple in updates)
            {
                //Console.WriteLine(tuple.Item1.Location + " reduction from " + unresWires.Get(tuple.Item1).Count + " to " + tuple.Item2.Count);
                unresWires.Set(tuple.Item1, tuple.Item2);
                if (tuple.Item2.Count == 0)
                {
                    unresWires.Remove(tuple.Item1.TileKey.X, tuple.Item1.TileKey.Y);
                }
            }
            Watch.Stop("Clean");

            Watch.Stop("ResolveWires");
        }
Beispiel #4
0
        private static Wire GetWire(string line, Tile containingTile, string wireName, bool beginPip, bool allowSkip, UnresolvedWires unresWires, out Tile targetTile)
        {
            targetTile = null;

            int firstBracketConn = line.IndexOf('(', 0);
            int firstBlankConn   = line.IndexOf(' ', firstBracketConn);
            int secondBlankConn  = line.IndexOf(' ', firstBlankConn + 1);

            string targetLocationString = line.Substring(firstBlankConn + 1, secondBlankConn - firstBlankConn - 1);

            // when parsing in incomplete files
            if (!FPGA.FPGA.Instance.Contains(targetLocationString))
            {
                return(null);
            }

            string targetLocationWireName = line.Substring(secondBlankConn + 1, line.Length - secondBlankConn - 2);

            targetTile = FPGA.FPGA.Instance.GetTile(targetLocationString);
            int xIncr = (targetTile.TileKey.X - containingTile.TileKey.X);
            int yIncr = (targetTile.TileKey.Y - containingTile.TileKey.Y);

            if (allowSkip && false)
            {
                if (!unresWires.ValidIdentifier(wireName) && !unresWires.ValidIdentifier(targetLocationWireName))
                {
                    return(null);
                }

                if (Math.Abs(xIncr) > 2 || Math.Abs(yIncr) > 2)
                {
                    return(null);
                }
            }

            uint wireNameKey = FPGA.FPGA.Instance.IdentifierListLookup.GetKey(wireName);
            uint targetLocationWireNameKey = FPGA.FPGA.Instance.IdentifierListLookup.GetKey(targetLocationWireName);

            Wire w = new Wire(
                wireNameKey,
                targetLocationWireNameKey,
                beginPip,
                xIncr,
                yIncr);

            return(w);
        }
Beispiel #5
0
        protected override void DoCommandAction()
        {
            if (!HandleUnresolvedWires)
            {
                FPGA.FPGA.Instance.ClearWireList();
            }
            m_loopWires = 0;

            // create reader & open file
            XDLStreamReaderWithUndo sr = new XDLStreamReaderWithUndo(FileName);
            XDLTileParser           tp = new XDLTileParser();

            UnresolvedWires unresWires = null;

            if (HandleUnresolvedWires)
            {
                unresWires = new UnresolvedWires();
            }

            try
            {
                Regex  tileFilter = new Regex(@"\t+\(tile", RegexOptions.Compiled);
                string line       = "";
                int    tileCount  = 0;
                while ((line = sr.ReadLine()) != null)
                {
                    // only consider tiles
                    if (tileFilter.IsMatch(line))
                    {
                        ProgressInfo.Progress = ProgressStart + ((int)((double)tileCount++ / (double)FPGA.FPGA.Instance.TileCount * ProgressShare));

                        int    yPos;
                        int    xPos;
                        string location;
                        XDLTileParser.GetTileHeaderData(line, out yPos, out xPos, out location);
                        Tile tile = FPGA.FPGA.Instance.GetTile(location);

                        Watch.Start("ParseWire");
                        tp.ParseWire(tile, sr, unresWires);
                        Watch.Stop("ParseWire");

                        if (HandleUnresolvedWires && tileCount % 10000 == 0)
                        {
                            ResolveWires(unresWires);
                            unresWires.ClearCache();
                        }
                    }
                }
            }
            catch (Exception error)
            {
                throw error;
            }
            finally
            {
                sr.Close();
            }

            if (!HandleUnresolvedWires)
            {
                // clean up data structures that were used for fast comparing wire list and are now no longer needed
                foreach (WireList wl in FPGA.FPGA.Instance.GetAllWireLists())
                {
                    wl.ClearWireKeys();
                }
            }
            else
            {
                ResolveWires(unresWires);
                OutputManager.WriteOutput("Added " + m_loopWires + " loop wires");
            }
        }