private bool AddArcsVivado(TCLContainer netlistContainer) { // which net to extend? TCLNet target; if (netlistContainer.Nets.Any(n => n.Name.Equals(Netname))) { target = (TCLNet)netlistContainer.GetNet(Netname); } else { target = (TCLNet)Net.CreateNet(Netname); target.IsBlockerNet = true; target.RoutingTree = new TCLRoutingTree(); TCLRoutingTreeNode root = new TCLRoutingTreeNode(null, null); root.VirtualNode = true; target.RoutingTree.Root = root; netlistContainer.Add(target); netlistContainer.AddGndPrimitive(target); } Port from = new Port(From); Port to = new Port(To); bool arcAdded = false; foreach (Tile tile in TileSelectionManager.Instance.GetSelectedTiles().Where(t => AddArcOnThisTile(from, to, t))) { TCLRoutingTreeNode driverNode = target.RoutingTree.Root.Children.FirstOrDefault(tile.Location, From); if (driverNode == null) { driverNode = new TCLRoutingTreeNode(tile, from); //driverNode.VivadoPipConnector = orderEl.VivadoPipConnector; target.RoutingTree.Root.Children.Add(driverNode); } TCLRoutingTreeNode leaveNode = new TCLRoutingTreeNode(tile, to); driverNode.Children.Add(leaveNode); // block ports if (!tile.IsPortBlocked(from, Tile.BlockReason.Blocked)) { tile.BlockPort(from, Tile.BlockReason.Blocked); } tile.BlockPort(to, Tile.BlockReason.Blocked); arcAdded = true; } return(arcAdded); }
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); } }
private bool Remove(TCLRoutingTreeNode node) { return(TileSelectionManager.Instance.IsSelected(node.Tile.TileKey)); }
private void CheckEnterLeave() { NetlistContainer nlc = GetNetlistContainer(); foreach (TCLNet net in nlc.Nets.Where(n => Regex.IsMatch(n.Name, Nets))) { Slice startSlice = FPGA.FPGA.Instance.GetSlice(net.OutpinInstance.SliceName); TCLRoutingTreeNode startPort = net.RoutingTree.Root.Children.First(); while (!Regex.IsMatch(startPort.Port.Name, StartPort)) { startPort = startPort.Children.First(); } Location startLoc = new Location(startSlice.ContainingTile, startPort.Port); bool startLocIsUserSelected = TileSelectionManager.Instance.IsUserSelected(startLoc.Tile.TileKey, ModulArea); Location currentLoc = startLoc; Location lastLoc = currentLoc; TCLRoutingTreeNode currentNode = startPort; TCLRoutingTreeNode violator; int hopCount = 0; while (true) { // TODO foreach lastLoc = currentLoc; currentLoc = Navigator.GetDestinations(currentLoc).FirstOrDefault(); violator = currentNode; currentNode = currentNode.Children.FirstOrDefault(); if (currentNode == null) { OutputManager.WriteWarning("Can not follow routing in net " + net.Name + " after using routing resources " + violator.Port.Name); break; } // stop over if (currentLoc == null) { Tuple <Port, Port> hop = lastLoc.Tile.SwitchMatrix.GetAllArcs().FirstOrDefault(t => t.Item1.Name.Equals(lastLoc.Pip.Name) && t.Item2.Name.Equals(currentNode.Port.Name)); currentLoc = new Location(lastLoc.Tile, hop.Item2); } if (currentLoc == null) { OutputManager.WriteWarning("Can not follow routing in net " + net.Name + " after using routing resources " + violator.Port.Name); break; } bool currentLocIsUserSelected = TileSelectionManager.Instance.IsUserSelected(currentLoc.Tile.TileKey, ModulArea); bool crossingBoundary = (startLocIsUserSelected && !currentLocIsUserSelected) || (!startLocIsUserSelected && currentLocIsUserSelected); if (crossingBoundary) { if (!Regex.IsMatch(violator.Port.Name, RoutingResources)) { OutputManager.WriteWarning("Unexpected routing resource " + violator.Port.Name + " in net " + net.Name + "used to enter/leave the reconfigurable area"); } break; } // update pip currentLoc = new Location(currentLoc.Tile, currentNode.Port); hopCount++; } } }