protected override void DoCommandAction() { FPGA.FPGATypes.AssertBackendType(FPGA.FPGATypes.BackendType.ISE); NetlistContainer netlistContainer = GetNetlistContainer(); Regex sourceNetFilter = new Regex(SourceNetsRegexp, RegexOptions.Compiled); Regex targetNetFilter = new Regex(TargetNetsRegexp, RegexOptions.Compiled); Regex pipFilter = new Regex(PipFilter, RegexOptions.Compiled); XDLNet targetNet = (XDLNet)netlistContainer.Nets.FirstOrDefault(n => targetNetFilter.IsMatch(n.Name)); if (targetNet == null) { throw new ArgumentException("Could not find a target net"); } foreach (XDLNet sourceNet in netlistContainer.Nets.Where(n => sourceNetFilter.IsMatch(n.Name))) { foreach (XDLPip pip in sourceNet.Pips.Where(p => pipFilter.IsMatch(p.Location))) { XDLPip copy = new XDLPip(pip.Location, pip.From, pip.Operator, pip.To); targetNet.Add(copy); } } }
protected override void DoCommandAction() { FPGATypes.AssertBackendType(FPGATypes.BackendType.ISE); NetlistContainer netlistContainer = GetNetlistContainer(); // extract net names as we may not remve during iteration List <XDLNet> netNamesToDecompose = new List <XDLNet>(); foreach (string netName in NetNames) { XDLNet n = (XDLNet)netlistContainer.GetNet(netName); netNamesToDecompose.Add(n); } foreach (XDLNet net in netNamesToDecompose) { foreach (XDLPip pip in net.Pips) { XDLNet arc = new XDLNet(net.Name + "_" + pip.Location + "_" + pip.From + "_" + pip.To); // TODO what about attributes arc.Add(pip); netlistContainer.Add(arc); } net.ClearPips(); if (net.NetPinCount == 0) { netlistContainer.Remove(new Predicate <Net>(n => n.Name.Equals(net.Name))); } } }
private IEnumerable <XDLPip> GetPipsToBlock(XDLNet n) { return(n.Pips.Where(p => !(IdentifierManager.Instance.IsMatch(p.Location, IdentifierManager.RegexTypes.CLB) || m_logicout.IsMatch(p.From) || m_logicout.IsMatch(p.To)))); }
private void GetSourceAndSink(NetlistContainer container, XDLNet net, out Tile source, out Tile sink) { // where is the outpin NetOutpin outPin = (NetOutpin)net.NetPins.Where(p => p is NetOutpin).First(); source = GetTile(container, outPin); List <Tile> tilesWithInpins = new List <Tile>(); if (TileSelectionManager.Instance.IsSelected(source.TileKey)) { foreach (NetPin pin in net.NetPins.Where(p => p is NetInpin && !IsInside(container, p))) { tilesWithInpins.Add(GetTile(container, pin)); } } else { foreach (NetPin pin in net.NetPins.Where(p => p is NetInpin && IsInside(container, p))) { tilesWithInpins.Add(GetTile(container, pin)); } } double x, y; TileSelectionManager.Instance.GetCenterOfTiles(tilesWithInpins, out x, out y); sink = FPGA.FPGA.Instance.GetTile((int)x, (int)y); }
protected override void DoCommandAction() { FPGATypes.AssertBackendType(FPGATypes.BackendType.ISE); NetlistContainer netlistContainer = GetNetlistContainer(); XDLNet net = (XDLNet )netlistContainer.GetNet(Netname); Regex filter = new Regex(PipRegexp, RegexOptions.Compiled); net.Remove(pip => filter.IsMatch(pip.ToString())); }
private bool Negative(XDLNet net) { if (string.IsNullOrEmpty(NegativeFilter)) { return(false); } else { return(Regex.IsMatch(net.Name, NegativeFilter)); } }
public void Add(Location location, Usage usage, XDLNet n) { if (!m_usages.ContainsKey(location)) { m_usages.Add(location, new List <Usage>()); } if (!m_usages[location].Contains(usage)) { m_usages[location].Add(usage); } }
protected override void DoCommandAction() { NetlistContainer m = GetNetlistContainer(); // build mapping: Location -> XDLNet Dictionary <string, Dictionary <string, XDLNet> > netConflicts = new Dictionary <string, Dictionary <string, XDLNet> >(); Dictionary <string, Dictionary <string, XDLPip> > pipConflicts = new Dictionary <string, Dictionary <string, XDLPip> >(); foreach (XDLNet n in m.Nets) { foreach (XDLPip pip in n.Pips) { if (!pip.Operator.Equals("->")) { continue; } if (!netConflicts.ContainsKey(pip.Location)) { netConflicts.Add(pip.Location, new Dictionary <string, XDLNet>()); pipConflicts.Add(pip.Location, new Dictionary <string, XDLPip>()); } // to if (!netConflicts[pip.Location].ContainsKey(pip.To)) { netConflicts[pip.Location].Add(pip.To, n); pipConflicts[pip.Location].Add(pip.To, pip); } else { XDLNet conflictingNet = netConflicts[pip.Location][pip.To]; XDLPip conflictingPip = pipConflicts[pip.Location][pip.To]; string conflict = " in " + pip.ToString() + " and " + conflictingPip; if (n.Name.Equals(conflictingNet.Name)) { OutputManager.WriteOutput("Detected driver conflift in net " + n.Name + conflict); } else { OutputManager.WriteOutput("Detected driver conflift between nets " + n.Name + " and " + netConflicts[pip.Location][pip.To].Name + conflict); } } } } }
public static string PathToString(Location start, Location sink, IEnumerable <List <Location> > paths) { Tile startTile = FPGA.FPGA.Instance.GetTile(start.Tile.Location); Port startPip = new Port(start.Pip.Name); Tile targetTile = FPGA.FPGA.Instance.GetTile(sink.Tile.Location); Port targetPip = new Port(sink.Pip.Name); NetOutpin op = new NetOutpin(); op.InstanceName = start.Tile.Location; op.SlicePort = start.Pip.Name; NetInpin ip = new NetInpin(); ip.InstanceName = sink.Tile.Location; ip.SlicePort = sink.Pip.Name; foreach (Slice s in startTile.Slices) { if (s.PortMapping.Contains(startPip)) { op.InstanceName = s.SliceName; } if (s.PortMapping.Contains(targetPip)) { ip.InstanceName = s.SliceName; } } int netCount = 0; StringBuilder buffer = new StringBuilder(); foreach (List <Location> path in paths.OrderBy(l => l.Count)) { XDLNet n = new XDLNet(path); n.Name = "path_" + netCount++; n.Add(op); n.Add(ip); buffer.AppendLine(n.ToString()); } return(buffer.ToString()); }
public XDLNet PathToNet(Location start, Location sink, List <Location> path) { Tile startTile = FPGA.FPGA.Instance.GetTile(start.Tile.Location); Port startPip = new Port(start.Pip.Name); Tile targetTile = FPGA.FPGA.Instance.GetTile(sink.Tile.Location); Port targetPip = new Port(sink.Pip.Name); NetOutpin op = new NetOutpin(); op.InstanceName = start.Tile.Location; op.SlicePort = start.Pip.Name; NetInpin ip = new NetInpin(); ip.InstanceName = sink.Tile.Location; ip.SlicePort = sink.Pip.Name; foreach (Slice s in startTile.Slices) { if (s.PortMapping.Contains(startPip)) { op.InstanceName = s.SliceName; } if (s.PortMapping.Contains(targetPip)) { ip.InstanceName = s.SliceName; } } XDLNet n = new XDLNet(path); n.Name = "path_0"; n.Add(op); n.Add(ip); return(n); }
protected override void DoCommandAction() { FPGATypes.AssertBackendType(FPGATypes.BackendType.ISE); NetlistContainer nlc = GetNetlistContainer(); // look for net with outping XDLNet anyNet = (XDLNet)nlc.Nets.FirstOrDefault(n => n.OutpinCount == 1 && string.IsNullOrEmpty(((XDLNet)n).HeaderExtension)); if (anyNet == null) { throw new ArgumentException("Could not a net with an outpin in " + NetlistContainerName); } // add outpin and inpin statements foreach (XDLNet net in nlc.Nets.Where(net => OtherArcsFilter(anyNet, net))) { anyNet.Add(net, false); // ports remain blocked net.ClearPips(); net.ClearPins(); } }
protected override void DoCommandAction() { NetlistContainer netlistContainer = GetNetlistContainer(); foreach (Tile probe in TileSelectionManager.Instance.GetSelectedTiles()) { if (probe.SwitchMatrix.GetAllArcs().Any(tupel => tupel.Item1.Name.Equals(From) && tupel.Item2.Name.Equals(To))) { XDLNet n = new XDLNet(probe.Location + "_" + From + "_" + To); n.Add(CommentForPip); n.Add(probe, new Port(From), new Port(To)); /* * probe.BlockPort(new Port(this.From), false); * probe.BlockPort(new Port(this.To), false);*/ netlistContainer.Add(n); } else { OutputManager.WriteOutput("Warning: Arc " + From + " -> " + To + " not found on tile " + probe.Location); } } }
public static XDLPip RelocatePip(Tile targetLocation, XDLPip pip, XDLNet targetNet) { if (!IdentifierManager.Instance.IsMatch(targetLocation.Location, IdentifierManager.RegexTypes.CLB)) { throw new ArgumentException("Expecting CLB"); } Tile referenceTile = FPGA.Instance.GetAllTiles().First(t => t.SwitchMatrix.Contains(pip.From, pip.To)); if (referenceTile == null) { throw new ArgumentException("Could not relocate " + pip.ToString() + " to tile " + targetLocation.Location); } int fromSliceIndex = -1; int toSliceIndex = -1; foreach (Slice s in referenceTile.Slices) { if (s.PortMapping.Contains(new Port(pip.From))) { fromSliceIndex = referenceTile.GetSliceNumberByName(s.SliceName); } if (s.PortMapping.Contains(new Port(pip.To))) { toSliceIndex = referenceTile.GetSliceNumberByName(s.SliceName); } } if (fromSliceIndex != toSliceIndex) { } Tuple <Port, Port> drivingArc = null; // route into slice if (fromSliceIndex == -1 && toSliceIndex != -1) { int lastUnderscore = pip.To.LastIndexOf("_"); string suffix = pip.To.Substring(lastUnderscore, pip.To.Length - lastUnderscore); Port sliceInPort = targetLocation.Slices[toSliceIndex].PortMapping.Ports.FirstOrDefault(p => p.Name.EndsWith(suffix)); drivingArc = targetLocation.SwitchMatrix.GetAllArcs().FirstOrDefault(t => t.Item2.Name.Equals(sliceInPort.Name)); } else if (fromSliceIndex != -1 && toSliceIndex == -1) { int lastUnderscore = pip.From.LastIndexOf("_"); string suffix = pip.From.Substring(lastUnderscore, pip.From.Length - lastUnderscore); Port sliceOutPort = targetLocation.Slices[fromSliceIndex].PortMapping.Ports.FirstOrDefault(p => p.Name.EndsWith(suffix)); // IsSlicePort: toSliceIndex is not found in slice, prevent using arcs that route in SLICE, i.e., prevent that CLBLL_L_AA -> IMUX get mapped to CLBLL_L_AA -> AMUX foreach (Tuple <Port, Port> candicate in targetLocation.SwitchMatrix.GetAllArcs().Where(t => t.Item1.Name.Equals(sliceOutPort.Name))) { string prefix = candicate.Item2.Name.Contains(" ") ? candicate.Item2.Name.Substring(0, candicate.Item2.Name.IndexOf(" ")) : candicate.Item2.Name; if (!targetLocation.IsSlicePort(prefix)) { drivingArc = candicate; break; } } //drivingArc = targetLocation.SwitchMatrix.GetAllArcs().FirstOrDefault(t => t.Item1.Name.Equals(sliceOutPort.Name) && !referenceTile.IsSlicePort(t.Item2.Name)); } else if (fromSliceIndex != -1 && toSliceIndex != -1) { int lastUnderscoreTo = pip.To.LastIndexOf("_"); string toSuffix = pip.To.Substring(lastUnderscoreTo, pip.To.Length - lastUnderscoreTo); Port toPort = targetLocation.Slices[toSliceIndex].PortMapping.Ports.FirstOrDefault(p => p.Name.EndsWith(toSuffix)); int lastUnderscoreFrom = pip.From.LastIndexOf("_"); string fromSuffix = pip.From.Substring(lastUnderscoreFrom, pip.From.Length - lastUnderscoreFrom); Port fromPort = targetLocation.Slices[fromSliceIndex].PortMapping.Ports.FirstOrDefault(p => p.Name.EndsWith(fromSuffix)); drivingArc = targetLocation.SwitchMatrix.GetAllArcs().FirstOrDefault(t => t.Item1.Name.Equals(fromPort.Name) && t.Item2.Name.StartsWith(toPort.Name)); } else { throw new ArgumentException("Could not relocate " + pip.ToString() + " to tile " + targetLocation.Location); } // cut of routethrough string relocatedToPortName = drivingArc.Item2.Name; if (relocatedToPortName.Contains(" ")) { relocatedToPortName = relocatedToPortName.Substring(0, relocatedToPortName.IndexOf(" ")); } XDLPip result = new XDLPip(targetLocation.Location, drivingArc.Item1.Name, pip.Operator, relocatedToPortName); return(result); /* * int indexOfFirstUnderScore = pip.From.IndexOf("_"); * String fromSuffix = pip.From.Substring(indexOfFirstUnderScore, pip.From.Length - indexOfFirstUnderScore); * * indexOfFirstUnderScore = pip.To.LastIndexOf("_"); * String toSuffix = pip.To.Substring(indexOfFirstUnderScore, pip.To.Length - indexOfFirstUnderScore); * * int tries = 0; * while (tries < 10) * { * foreach (Port from in targetLocation.SwitchMatrix.Ports.Where(p => p.Name.EndsWith(fromSuffix) && targetLocation.GetSliceNumberByPortName(p) == fromSliceIndex)) * { * foreach (Port p in targetLocation.SwitchMatrix.GetDrivenPorts(from).Where(p => targetLocation.GetSliceNumberByPortName(p) == toSliceIndex)) * { * String portNameWithoutRouteThrough = p.Name; * if (p.Name.Contains(" ")) * { * portNameWithoutRouteThrough = p.Name.Substring(0, p.Name.IndexOf(" ")); * } * if (portNameWithoutRouteThrough.EndsWith(toSuffix)) * { * if (targetLocation.SwitchMatrix.Contains(from.Name, p.Name)) * { * XDLPip result = new XDLPip(targetLocation.Location, from.Name, pip.Operator, portNameWithoutRouteThrough); * return result; * } * } * } * } * if (fromSuffix.Length > 1) * { * fromSuffix = fromSuffix.Substring(1, fromSuffix.Length - 1); * } * tries++; * } */ throw new ArgumentException("Could not relocate " + pip.ToString() + " to tile " + targetLocation.Location); }
private void AddBlockerPaths(Net blockerNet, Tile first, IEnumerable <Tile> cluster) { XDLNet xdlNet = null; TCLNet TCLNet = null; if (blockerNet is XDLNet) { xdlNet = (XDLNet)blockerNet; } else if (blockerNet is TCLNet) { TCLNet = (TCLNet)blockerNet; } bool firstArcInCluster = true; // user defined paths foreach (BlockerPath bp in BlockerSettings.Instance.GetAllBlockerPaths()) { Regex hopRegexp = GetRegex(bp.HopRegexp); Regex driverRegexp = GetRegex(bp.DriverRegexp); Regex sinkRegexp = GetRegex(bp.SinkRegexp); // TODO add port filter foreach (Port hop in first.SwitchMatrix.Ports.Where(p => hopRegexp.IsMatch(p.Name) && !first.IsPortBlocked(p))) { Tuple <Port, Port> arc1 = first.SwitchMatrix.GetFirstArcOrDefault( p => !first.IsPortBlocked(p) && !BlockerSettings.Instance.SkipPort(p) && driverRegexp.IsMatch(p.Name), arc => arc.Item2.Name.Equals(hop.Name) && !BlockerSettings.Instance.SkipPort(arc.Item2)); if (arc1.Item1 != null && arc1.Item2 != null) { Tuple <Port, Port> arc2 = first.SwitchMatrix.GetFirstArcOrDefault( p => p.Name.Equals(hop.Name) && !BlockerSettings.Instance.SkipPort(p), arc => !BlockerSettings.Instance.SkipPort(arc.Item2) && sinkRegexp.IsMatch(arc.Item2.Name) && !first.IsPortBlocked(arc.Item2)); if (arc2.Item1 != null && arc2.Item2 != null) { foreach (Tile t in cluster) { if (xdlNet != null) { // comment on first application of this rule if (firstArcInCluster) { xdlNet.Add("added by BlockSelection.BlockerPath"); firstArcInCluster = false; } // extend path xdlNet.Add(t, arc1.Item1, arc1.Item2); xdlNet.Add(t, arc2.Item1, arc2.Item2); } if (TCLNet != null) { firstArcInCluster = false; TCLRoutingTreeNode driverNode = TCLNet.RoutingTree.Root.Children.FirstOrDefault(t.Location, arc1.Item1.Name); if (driverNode == null) { driverNode = new TCLRoutingTreeNode(t, arc1.Item1); TCLNet.RoutingTree.Root.Children.Add(driverNode); } TCLRoutingTreeNode hopNode = TCLNet.RoutingTree.Root.Children.FirstOrDefault(t.Location, arc1.Item2.Name); if (hopNode == null) { hopNode = new TCLRoutingTreeNode(t, arc1.Item2); driverNode.Children.Add(hopNode); } // sink node should never exist! TCLRoutingTreeNode sinkNode = new TCLRoutingTreeNode(t, arc2.Item2); hopNode.Children.Add(sinkNode); } BlockPort(t, arc1.Item1); BlockPort(t, arc1.Item2); BlockPort(t, arc2.Item2); } } } } } }
private void AddArcs(Net blockerNet, Tile first, IEnumerable <Tile> cluster) { XDLNet xdlNet = null; TCLNet TCLNet = null; if (blockerNet is XDLNet) { xdlNet = (XDLNet)blockerNet; } else if (blockerNet is TCLNet) { TCLNet = (TCLNet)blockerNet; } bool firstArcInCluster = true; foreach (BlockerOrderElement orderEl in BlockerSettings.Instance.GetBlockerOrder()) { if (!BlockWithEndPips && orderEl.EndPip) { continue; } Regex driverMatch = GetRegex(orderEl.DriverRegexp); // as as many arc as possible foreach (Port driver in first.SwitchMatrix.GetAllDriversSortedAscByConnectivity(p => !first.IsPortBlocked(p) && driverMatch.IsMatch(p.Name) && !BlockerSettings.Instance.SkipPort(p) && !first.IsPortBlocked(p.Name, Tile.BlockReason.ExcludedFromBlocking))) { Regex sinkMatch = GetRegex(orderEl.SinkRegexp); //foreach (Port drivenPort in first.SwitchMatrix.GetDrivenPortsSortedSortedDescByConnectivity(driver, p => foreach (Port drivenPort in first.SwitchMatrix.GetDrivenPorts(driver).Where(p => !first.IsPortBlocked(p) && sinkMatch.IsMatch(p.Name) && !BlockerSettings.Instance.SkipPort(p) && !first.IsPortBlocked(p.Name, Tile.BlockReason.ExcludedFromBlocking))) { foreach (Tile t in cluster) { if (xdlNet != null) { // comment on first application of rule if (firstArcInCluster) { xdlNet.Add(" added by BlockSelection: " + orderEl.ToString()); firstArcInCluster = false; } // extend net xdlNet.Add(t, driver, drivenPort); } else if (TCLNet != null) { //TCLRoutingTreeNode driverNode = xdlNet.RoutingTree.Root.Children.FirstOrDefault(n => n.Tile.Location.Equals(t.Location) && n.Port.Name.Equals(driver.Name)); TCLRoutingTreeNode driverNode = TCLNet.RoutingTree.Root.Children.FirstOrDefault(t.Location, driver.Name); if (driverNode == null) { driverNode = new TCLRoutingTreeNode(t, driver); driverNode.VivadoPipConnector = orderEl.VivadoPipConnector; TCLNet.RoutingTree.Root.Children.Add(driverNode); } TCLRoutingTreeNode leaveNode = new TCLRoutingTreeNode(t, drivenPort); driverNode.Children.Add(leaveNode); } BlockPort(t, driver); BlockPort(t, drivenPort); } if (!orderEl.ConnectAll) { break; } } } } }
private void RelocateNetsForXDL(LibraryElement libElement, Tile anchorCLB, XDLContainer netlistContainer) { foreach (XDLNet net in libElement.Containter.Nets) { // insert instance prefix XDLNet relocatedNet = new XDLNet(InstanceName + net.Name); relocatedNet.HeaderExtension = net.HeaderExtension; foreach (NetPin pin in net.NetPins) { NetPin copy = NetPin.Copy(pin); if (InsertPrefix) { // insert instance prefix // remove greedy between double quotes string oldInstanceName = pin.InstanceName; string newInstanceName = "\"" + InstanceName + Regex.Replace(oldInstanceName, "\"", "") + "\""; //xdlCode = Regex.Replace(xdlCode, oldInstanceName, newInstanceName); copy.InstanceName = newInstanceName; copy.InstanceName = copy.InstanceName.Replace("\"", ""); } relocatedNet.Add(copy); } //foreach (NetSegment seg in originalNet.GetAllSegments()) foreach (XDLPip pip in net.Pips) { string targetLocation; bool success = libElement.GetTargetLocation(pip.Location, anchorCLB, out targetLocation); Tile targetTile = null; if (FPGA.FPGA.Instance.Contains(targetLocation)) { targetTile = FPGA.FPGA.Instance.GetTile(targetLocation); } else { throw new ArgumentException("Error during relocation of pip " + pip + " to " + targetLocation); } XDLPip relocatedSegment = null; if (targetTile.SwitchMatrix.Contains(pip.From, pip.To)) { // we do not need to transform identifiers relocatedSegment = new XDLPip(targetTile.Location, pip.From, pip.Operator, pip.To); } else { // naming fun relocatedSegment = FPGATypes.RelocatePip(targetTile, pip, relocatedNet); } if (relocatedSegment == null) { throw new ArgumentException("Could not relocate " + pip.ToString() + " to tile " + targetLocation); } if (!targetTile.SwitchMatrix.Contains(relocatedSegment.From, relocatedSegment.To)) { throw new ArgumentException("Could not relocate " + pip.ToString() + " to tile " + targetLocation); } relocatedNet.Add(relocatedSegment); } if (netlistContainer.Nets.Any(n => n.Name.Equals(relocatedNet.Name))) { throw new ArgumentException("A net named " + relocatedNet.Name + " is alredy inserted to netlist " + netlistContainer.Name + ". Did you try to join two instances of the same macro in one?"); } netlistContainer.Add(relocatedNet); } }
protected override void DoCommandAction() { // read input Queue <Tuple <Location, Location> > fromToTuples = null; ReadSearchInput(out fromToTuples); // result List <List <Location> > paths = new List <List <Location> >(); List <XDLNet> nets = new List <XDLNet>(); RouteNet routeCmd = new RouteNet(); routeCmd.Watch = Watch; int size = fromToTuples.Count; int count = 0; UsageManager usageManager = new UsageManager(); // upon sink chnmage, block the last nets Location lastSink = null; while (fromToTuples.Count > 0) { ProgressInfo.Progress = ProgressStart + (int)((double)count++ / (double)size * ProgressShare); Tuple <Location, Location> tuple = fromToTuples.Dequeue(); Location source = tuple.Item1; Location sink = tuple.Item2; bool pathFound = false; bool sinkChange = lastSink == null ? false : !lastSink.Equals(sink); lastSink = sink; if (sinkChange) { BlockPips(nets); } Usage usage = new Usage(source, sink); //if (source.Tile.Location.Equals("CLEXL_X22Y16") && source.Pip.Name.Equals("XX_AQ") && sink.Tile.Location.Equals("CLEXM_X23Y18") && sink.Pip.Name.Equals("X_AX")) if (source.Tile.Location.Equals("CLEXL_X22Y16") && source.Pip.Name.Equals("XX_AQ") && sink.Tile.Location.Equals("CLEXM_X23Y16") && sink.Pip.Name.Equals("X_AX")) { } List <Location> initialSearchFront = new List <Location>(); foreach (Location location in usageManager.GetLocationsWithExclusiveUsage(usage).OrderBy(l => Distance(l, sink))) { initialSearchFront.Add(location); } // add default source after the others initialSearchFront.Add(source); // truncate on first run TextWriter tw = new StreamWriter(OutputFile, count > 1); tw.Write(PathSearchOnFPGA.GetBanner(source, sink)); //Console.WriteLine("Running path " + count + " " + usage + (initialSearchFront.Count > 1 ? " with shortcut" : "")); if (initialSearchFront.Count > 1) { } Watch.Start("search"); foreach (List <Location> path in routeCmd.Route("BFS", true, initialSearchFront, sink, 100, MaxDepth, false)) { if (!PathSearchOnFPGA.PathAlreadyFound(path, paths)) { paths.Add(path); XDLNet n = PathToNet(source, sink, path); nets.Add(n); usage.Net = n; tw.Write(PathSearchOnFPGA.PathToString(source, sink, Enumerable.Repeat(path, 1))); pathFound = true; // no blocking on CLEX LOGIC foreach (XDLPip pip in GetPipsToBlock(n)) { Location l = new Location(FPGA.FPGA.Instance.GetTile(pip.Location), new Port(pip.From)); //Location r = new Location(FPGA.FPGA.Instance.GetTile(pip.Location), new Port(pip.To)); usageManager.Add(l, usage, n); //usageManager.Add(r, usage); } break; } } Watch.Stop("search"); if (!pathFound) { tw.WriteLine("No path found"); string trigger = ("if (source.Tile.Location.Equals(\"" + source.Tile.Location + "\") && source.Pip.Name.Equals(\"" + source.Pip.Name + "\") && sink.Tile.Location.Equals(\"" + sink.Tile.Location + "\") && sink.Pip.Name.Equals(\"" + sink.Pip.Name + "\"))"); Console.WriteLine(trigger); } tw.Close(); if (nets.Count % 20 == 0) { // Console.WriteLine(this.Watch.GetResults()); } } }
protected override void DoCommandAction() { if (FPGA.FPGA.Instance.BackendType == FPGATypes.BackendType.Vivado) { return; } FPGATypes.AssertBackendType(FPGATypes.BackendType.ISE); NetlistContainer nlc = GetNetlistContainer(); int workload = GetNetsToDecomposeWithOutpin().Count(); int count = 0; List <XDLNet> newNets = new List <XDLNet>(); foreach (XDLNet net in GetNetsToDecomposeWithOutpin().Where(n => n.PRLink)) { ProgressInfo.Progress = ProgressStart + (int)((double)count++ / (double)workload * ProgressShare); Dictionary <string, List <XDLPip> > pipsToRemove = null; // decompose nets without outpin. // e.g., placing a module on connection macros wil remove outpins from certain I/O bar wires if (net.NetPins.Where(np => np is NetOutpin).Count() == 0) { pipsToRemove = new Dictionary <string, List <XDLPip> >(); foreach (XDLPip pip in net.Pips) { if (!pipsToRemove.ContainsKey(pip.Location)) { pipsToRemove.Add(pip.Location, new List <XDLPip>()); } pipsToRemove[pip.Location].Add(pip); } } else { bool antenna = net.IsAntenna(out pipsToRemove); } bool firstArc = true; // values are all non empty litst foreach (List <XDLPip> l in pipsToRemove.Values) { foreach (XDLPip pip in l) { if (firstArc) { firstArc = false; //this.OutputManager.WriteOutput("Decomposing net " + net.Name); } XDLNet arc = new XDLNet(net.Name + "_arc_" + pip.Location + "_" + pip.From + "_" + pip.To); //arc.AddComment("decomposed from net (with outpin) " + net.Name); // TODO what about attributes? arc.Add(pip); // move inpins List <NetPin> netPinsToRemove = new List <NetPin>(); foreach (NetPin netpin in net.NetPins.Where(np => np is NetInpin)) { XDLInstance inst = (XDLInstance)nlc.GetInstanceByName(netpin.InstanceName); Tile pipTile = FPGA.FPGA.Instance.GetTile(pip.Location); if (pipTile.TileKey.Equals(inst.TileKey)) { //netpin.Comment += "taken from " + net.Name; arc.Add(netpin); // store net pip for later removal as we may not change the collection during iterating over it netPinsToRemove.Add(netpin); } } // remove the inpins from the original net ... net.RemoveAllPinStatements(np => netPinsToRemove.Contains(np)); // ... and remove the arc from the original net newNets.Add(arc); } } // only invoke Remove once per net (blocker is very slow) net.Remove(p => PipFilter(p, pipsToRemove)); } // decompose blocker net foreach (XDLNet net in GetNetsToDecomposeWithoutOutpin()) { foreach (XDLPip pip in net.Pips) { XDLNet arc = new XDLNet(net.Name + "_arc_" + pip.Location + "_" + pip.From + "_" + pip.To); //arc.AddComment("decomposed from net (without outpin) " + net.Name); // TODO what about attributes? arc.Add(pip); newNets.Add(arc); } // remove all pips net.ClearPips(); } // add arcs foreach (XDLNet n in newNets) { nlc.Add(n); } }
public static IEnumerable <LocationOutsideNet> AllLocationsOutsideNet(Net net) { Dictionary <string, List <string> > locations = new Dictionary <string, List <string> >(); switch (FPGA.FPGA.Instance.BackendType) { case FPGATypes.BackendType.ISE: XDLNet xdlNet = (XDLNet)net; foreach (XDLPip pip in xdlNet.Pips) { if (!locations.ContainsKey(pip.Location)) { locations.Add(pip.Location, new List <string>()); } locations[pip.Location].Add(pip.From); } foreach (XDLPip pip in xdlNet.Pips) { if (pip.Operator.Equals("=-")) { foreach (Location loc in Navigator.GetDestinations(pip.Location, pip.From)) { if (!locations.ContainsKey(loc.Tile.Location)) { yield return(new LocationOutsideNet(loc, pip)); } else { if (!locations[loc.Tile.Location].Contains(loc.Pip.Name)) { yield return(new LocationOutsideNet(loc, pip)); } } } } // find all arcs that do not end up in this net foreach (Location loc in Navigator.GetDestinations(pip.Location, pip.To)) { if (!locations.ContainsKey(loc.Tile.Location)) { yield return(new LocationOutsideNet(loc, pip)); } else { if (!locations[loc.Tile.Location].Contains(loc.Pip.Name)) { yield return(new LocationOutsideNet(loc, pip)); } } } // consider stopovers yield return(new LocationOutsideNet(new Location(FPGA.FPGA.Instance.GetTile(pip.Location), new Port(pip.To)), pip)); } break; case FPGATypes.BackendType.Vivado: TCLNet tclNet = (TCLNet)net; foreach (TCLRoutingTreeNode node in tclNet.RoutingTree.GetAllRoutingNodes().Where(n => !n.VirtualNode)) { if (!locations.ContainsKey(node.Tile.Location)) { locations.Add(node.Tile.Location, new List <string>()); } locations[node.Tile.Location].Add(node.Port.Name); } // find all arcs that do not end up in this net foreach (TCLRoutingTreeNode node in tclNet.RoutingTree.GetAllRoutingNodes().Where(n => !n.VirtualNode)) { List <Port> driven = new List <Port>(); // outside driven.Add(node.Port); // inside switch matrix driven.AddRange(node.Tile.SwitchMatrix.GetDrivenPorts(node.Port)); foreach (Port p in driven) { foreach (Location loc in Navigator.GetDestinations(node.Tile.Location, p.Name)) { if (!locations.ContainsKey(loc.Tile.Location)) { yield return(new LocationOutsideNet(loc, node)); foreach (Port reachable in loc.Tile.SwitchMatrix.GetDrivenPorts(loc.Pip)) { if (reachable.Name.Contains("EE2")) { } Location other = new Location(loc.Tile, reachable); yield return(new LocationOutsideNet(other, node)); } } else { if (!locations[loc.Tile.Location].Contains(loc.Pip.Name)) { yield return(new LocationOutsideNet(loc, node)); } } } } // TODO // consider stopovers // ?? yield return new LocationOutsideNet(new Location(FPGA.FPGA.Instance.GetTile(pip.Location), new Port(pip.To)), pip); } break; } }
private bool Positive(XDLNet net) { return(Regex.IsMatch(net.Name, PositiveFilter)); }
protected override void DoCommandAction() { FPGATypes.AssertBackendType(FPGATypes.BackendType.ISE); // read file DesignParser parser = DesignParser.CreateDesignParser(XDLInFile); // into design XDLContainer container = new XDLContainer(); parser.ParseDesign(container, this); XDLNet netWithOutPin = (XDLNet)container.Nets.FirstOrDefault(n => n.OutpinCount == 1 && string.IsNullOrEmpty(((XDLNet)n).HeaderExtension)); if (netWithOutPin == null) { throw new ArgumentException("No net with outpin found"); } List <string> namesOfNetsWithoutOutpin = new List <string>(); foreach (Net net in container.Nets.Where(n => n.OutpinCount == 0)) { namesOfNetsWithoutOutpin.Add(net.Name); } foreach (string netName in namesOfNetsWithoutOutpin) { XDLNet net = (XDLNet)container.Nets.FirstOrDefault(n => n.Name.Equals(netName)); if (net == null) { throw new ArgumentException("Net " + netName + " not found"); } foreach (XDLPip pip in net.Pips) { netWithOutPin.Add(pip); } net.ClearPips(); } System.IO.TextWriter tw = new System.IO.StreamWriter(XDLOutFile, false); tw.WriteLine(container.GetDesignConfig().ToString()); foreach (XDLModule mod in container.Modules) { tw.WriteLine(mod.ToString()); } foreach (XDLPort p in container.Ports) { tw.WriteLine(p.ToString()); } foreach (XDLInstance inst in container.Instances) { tw.WriteLine(inst.ToString()); } foreach (XDLNet net in container.Nets) { tw.WriteLine(net.ToString()); } tw.Close(); }
protected override void DoCommandAction() { FPGATypes.AssertBackendType(FPGATypes.BackendType.ISE); // what to route NetlistContainer netlist = GetNetlistContainer(); XDLNet netToRoute = (XDLNet)netlist.GetNet(NetName); int outpinCount = netToRoute.NetPins.Count(np => np is NetOutpin); if (outpinCount != 1) { throw new ArgumentException("Can not route nets with " + outpinCount + " outpins"); } NetPin outpin = netToRoute.NetPins.First(np => np is NetOutpin); // start to route from here List <Location> startLocations = new List <Location>(); List <Location> targetLocations = new List <Location>(); // route from outpin string startTileName = netlist.GetInstanceByName(outpin.InstanceName).Location; Tile startTile = FPGA.FPGA.Instance.GetTile(startTileName); Slice startSlice = startTile.GetSliceByName(netlist.GetInstanceByName(outpin.InstanceName).SliceName); Port startPip = startSlice.PortMapping.Ports.Where(p => p.Name.EndsWith(outpin.SlicePort)).First(); Location outpinLocation = new Location(startTile, startPip); startLocations.Add(outpinLocation); Queue <Location> targetQueue = new Queue <Location>(targetLocations); foreach (NetPin inpin in netToRoute.NetPins.Where(np => np is NetInpin).OrderBy(np => np.InstanceName)) { string targetTileName = netlist.GetInstanceByName(inpin.InstanceName).Location; Tile targetTile = FPGA.FPGA.Instance.GetTile(targetTileName); Slice targetSlice = targetTile.GetSliceByName(netlist.GetInstanceByName(inpin.InstanceName).SliceName); Port targetPip = targetSlice.PortMapping.Ports.Where(p => p.Name.EndsWith(inpin.SlicePort)).First(); Location inpinLocation = new Location(targetTile, targetPip); targetQueue.Enqueue(inpinLocation); } while (targetQueue.Count > 0) { // start with new routing foreach (XDLPip pip in netToRoute.Pips) { Tile newStartTile = FPGA.FPGA.Instance.GetTile(pip.Location); startLocations.Add(new Location(newStartTile, new Port(pip.From))); } // dequeue next target Location targetLocation = targetQueue.Dequeue(); Watch.Start("route"); List <Location> revPath = Route(SearchMode, true, startLocations, targetLocation, 0, 100, false).FirstOrDefault(); Watch.Stop("route"); // extend net if (revPath != null) { XDLNet extension = new XDLNet(revPath); netToRoute.Add(extension); } } // block the added pips netToRoute.BlockUsedResources(); }
private void FuseXDLNets(NetlistContainer netlistContainer) { Queue <Net> netsWithOutpin = FindNetsWithOutpin(netlistContainer); Dictionary <string, Net> netsToConsiderForFusing = FindNetsToConsiderForFusing(netlistContainer); // build mapping: Location -> XDLNet Dictionary <string, Dictionary <string, List <Net> > > candidateLocations = BuildLocationNetMapping(netlistContainer); int startSize = netsWithOutpin.Count; while (netsWithOutpin.Count > 0) { XDLNet current = (XDLNet )netsWithOutpin.Dequeue(); ProgressInfo.Progress = (int)((double)(startSize - netsWithOutpin.Count) / (double)startSize * 100); while (netsToConsiderForFusing.Count > 0) { Dictionary <string, XDLNet> fusedNets = new Dictionary <string, XDLNet>(); Dictionary <string, Location> fusePoints = new Dictionary <string, Location>(); // route from end of antennas foreach (LocationOutsideNet los in AllLocationsOutsideNet(current)) { Location loc = los.Location; if (!candidateLocations.ContainsKey(loc.Tile.Location)) { continue; } if (!candidateLocations[loc.Tile.Location].ContainsKey(loc.Pip.Name)) { continue; } List <string> netNamesToRemove = new List <string>(); foreach (XDLNet n in candidateLocations[loc.Tile.Location][loc.Pip.Name]) { if (!fusedNets.ContainsKey(n.Name) && !n.Name.Equals(current.Name) && netsToConsiderForFusing.ContainsKey(n.Name)) { fusedNets.Add(n.Name, n); fusePoints.Add(n.Name, loc); netNamesToRemove.Add(n.Name); } } candidateLocations[loc.Tile.Location][loc.Pip.Name].RemoveAll(net => netNamesToRemove.Contains(net.Name)); } // and check for branches branches foreach (XDLPip pip in current.Pips) { if (!candidateLocations.ContainsKey(pip.Location)) { continue; } if (!candidateLocations[pip.Location].ContainsKey(pip.From)) { continue; } List <string> netNamesToRemove = new List <string>(); foreach (XDLNet n in candidateLocations[pip.Location][pip.From]) { if (!fusedNets.ContainsKey(n.Name) && !n.Name.Equals(current.Name) && netsToConsiderForFusing.ContainsKey(n.Name)) { fusedNets.Add(n.Name, n); fusePoints.Add(n.Name, new Location(FPGA.FPGA.Instance.GetTile(pip.Location), new Port(pip.From))); netNamesToRemove.Add(n.Name); } } candidateLocations[pip.Location][pip.From].RemoveAll(net => netNamesToRemove.Contains(net.Name)); } foreach (XDLNet net in fusedNets.Values) { // do not add comments to pips or nets to save memory // TODO nur die nasen dranhaengen, die vom current treiber erreichbar sind // TODO attribute fusionieren current.Add(net, false, ""); //current.Add(net, true, "taken from " + net.Name); if (!string.IsNullOrEmpty(net.Header)) { if (net.Header.Contains("vcc") || net.Header.Contains("gnd")) { OutputManager.WriteWarning("Attribute lost: " + net.Header); } } OutputManager.WriteOutput("Fusing " + current.Name + " with " + net.Name + " @" + fusePoints[net.Name].ToString()); //this.OutputManager.WriteOutput(net.ToString()); //this.OutputManager.WriteOutput(net.Foo()); //this.OutputManager.WriteOutput("------------------------------------------------"); //netlistContainer.RemoveNet(net.Name); netlistContainer.Remove(delegate(Net n) { return(n.Name.Equals(net.Name)); }); netsToConsiderForFusing.Remove(net.Name); } // no futher fusions made, continue with next net if (fusedNets.Count == 0) { break; } } } }
private void RemovePipsFromNet(XDLContainer netlistContainer, Dictionary <string, bool> targetLocations, XDLNet net) { int pipCount = net.PipCount; net.Remove(p => targetLocations.ContainsKey(p.Location)); net.RemoveAllPinStatements(np => targetLocations.ContainsKey(netlistContainer.GetInstance(np).Location)); // pip count changed -> probably a PRLink that may be decomposed if (pipCount != net.PipCount) { net.PRLink = true; } }