private void RelocateNetsForTCL(LibraryElement libElement, Tile anchorCLB, NetlistContainer netlistContainer) { foreach (TCLNet net in libElement.Containter.Nets) { TCLNet relocatedNet = TCLNet.Relocate(net, libElement, anchorCLB); relocatedNet.Name = InstanceName + relocatedNet.Name; // relocate NetPins foreach (NetPin pin in relocatedNet.NetPins) { if (InsertPrefix) { pin.InstanceName = InstanceName + pin.InstanceName; } } netlistContainer.Add(relocatedNet); } }
private void FuseTCLNets(NetlistContainer netlistContainer) { Queue <Net> netsWithOutpin = FindNetsWithOutpin(netlistContainer); Dictionary <string, Net> netsToConsiderForFusing = FindNetsToConsiderForFusing(netlistContainer); // build mapping: Location -> XDLNet WEITER HIER Dictionary <string, Dictionary <string, List <Net> > > candidateLocations = BuildLocationNetMapping(netlistContainer); int startSize = netsWithOutpin.Count; while (netsWithOutpin.Count > 0) { TCLNet current = (TCLNet)netsWithOutpin.Dequeue(); if (current.Name.Contains("p2s")) { } ProgressInfo.Progress = (int)((double)(startSize - netsWithOutpin.Count) / (double)startSize * 100); while (netsToConsiderForFusing.Count > 0) { Dictionary <string, Net> fusedNets = new Dictionary <string, Net>(); Dictionary <string, LocationOutsideNet> fusePoints = new Dictionary <string, LocationOutsideNet>(); // 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)) { Dictionary <string, List <Net> > debug = candidateLocations[loc.Tile.Location]; continue; } List <string> netNamesToRemove = new List <string>(); foreach (Net 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, los); netNamesToRemove.Add(n.Name); //((TCLRoutingTreeNode)los.RoutingElement).Children.Add() } } candidateLocations[loc.Tile.Location][loc.Pip.Name].RemoveAll(net => netNamesToRemove.Contains(net.Name)); } // TDOO see "and check for branches branches" foreach (TCLNet net in fusedNets.Values) { 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); foreach (NetPin np in net.NetPins) { current.Add(np); } current.FlattenNet(); net.FlattenNet(); foreach (TCLRoutingTreeNode child in net.RoutingTree.Root.Children) { current.RoutingTree.Root.Children.Add(child); } } // no futher fusions made, continue with next net if (fusedNets.Count == 0) { break; } } } }
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 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; } } } } }
protected override void DoCommandAction() { BlockOnlyMarkedPortsScope = BlockOnlyMarkedPorts; FPGATypes.AssertBackendType(FPGATypes.BackendType.ISE, FPGATypes.BackendType.Vivado); // prevent repeated error message from subcommands if (!NetlistContainerManager.Instance.Contains(NetlistContainerName)) { throw new ArgumentException("The netlist container " + NetlistContainerName + " does not exist. Use the command AddNetlistContainer to add a netlist container."); } NetlistContainer nlc = GetNetlistContainer(); Net blockerNet = null; bool useExistingNet = false; if (nlc.Nets.Any(n => n.OutpinCount > 0)) { useExistingNet = true; blockerNet = nlc.GetAnyNet(); OutputManager.WriteOutput("Adding blocker pips to already existing net " + blockerNet.Name); } else { // create XDL or TCL script blockerNet = Net.CreateNet("BlockSelection"); if (FPGA.FPGA.Instance.BackendType == FPGATypes.BackendType.Vivado) { blockerNet = new TCLNet("BlockSelection"); //((TCLNet)blockerNet).Properties.SetProperty("IS_ROUTE_FIXED", "TRUE", false); // tag for code generation ((TCLNet)blockerNet).IsBlockerNet = true; ((TCLNet)blockerNet).RoutingTree = new TCLRoutingTree(); TCLRoutingTreeNode root = new TCLRoutingTreeNode(null, null); root.VirtualNode = true; ((TCLNet)blockerNet).RoutingTree.Root = root; } useExistingNet = false; bool outPinAdded = false; // the location string of the tile in which we run the outpin string outpinLocation = ""; // 1 iterate over all not filtered out tiles to instantiate primitves and to find an outpin switch (FPGA.FPGA.Instance.BackendType) { case FPGATypes.BackendType.ISE: AddXDLTemplates(nlc, blockerNet, ref outPinAdded, ref outpinLocation); break; case FPGATypes.BackendType.Vivado: //this.AddTCLInstances(nlc, blockerNet, ref outPinAdded, ref outpinLocation); ((TCLContainer)nlc).AddGndPrimitive(blockerNet); outPinAdded = true; break; } // 2 name net according to added outpin blockerNet.Name = Prefix + outpinLocation + "_" + blockerNet.Name; if (!outPinAdded) { OutputManager.WriteOutput("Could not find an outpin"); } } // 4 cluster all completely unblocked tiles by their identifiers (do not cluster BEFORE having added and thus blocked an outpin) // tiles with already blocked ports are added to single cluster each and thus treated seperately Dictionary <int, List <Tile> > clusteredTiles = new Dictionary <int, List <Tile> >(); switch (FPGA.FPGA.Instance.BackendType) { case FPGATypes.BackendType.ISE: FindClusteringForISE(clusteredTiles); break; case FPGATypes.BackendType.Vivado: FindClusteringForVivado(clusteredTiles); break; } // block by // 5 paths ... int clusterCount = 0; foreach (List <Tile> tiles in clusteredTiles.Values) { AddBlockerPaths(blockerNet, tiles[0], tiles); ProgressInfo.Progress = 0 + (int)((double)clusterCount++ / (double)clusteredTiles.Count * 50); } // 6 and arcs clusterCount = 0; foreach (List <Tile> tiles in clusteredTiles.Values) { AddArcs(blockerNet, tiles[0], tiles); ProgressInfo.Progress = 50 + (int)((double)clusterCount++ / (double)clusteredTiles.Count * 50); } // 7 check blocking if (PrintUnblockedPorts) { foreach (Tile t in TileSelectionManager.Instance.GetSelectedTiles().Where( t => !BlockerSettings.Instance.SkipTile(t) && IdentifierManager.Instance.IsMatch(t.Location, IdentifierManager.RegexTypes.Interconnect))) { CheckForUnblockedPorts(t); } } // clean up indeces foreach (Tile tile in TileSelectionManager.Instance.GetSelectedTiles().Where(t => !BlockerSettings.Instance.SkipTile(t))) { tile.SwitchMatrix.ClearBlockingPortList(); } // add prefix and store nets if (blockerNet.PipCount > 0 && !useExistingNet) { nlc.Add(blockerNet); } }