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))); } } }
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() { 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); } } }
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(); } }
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 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() { 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); } }
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(); }