private Tile GetTile(NetlistContainer container, NetPin pin) { Instance instance = container.GetInstanceByName(pin.InstanceName); Tile instanceTile = FPGA.FPGA.Instance.GetTile(instance.Location); return(instanceTile); }
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); // 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(); }