/// <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; } } }
//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); }
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"); }
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); }
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"); } }