private void WriteHierarchyCells(TCLContainer nlc) { foreach (TCLDesignHierarchy hier in nlc.Hierarchies) { m_sw.WriteLine("create_cell -reference " + hier.Properties.GetValue("REF_NAME") + " -black_box " + hier.Name); } }
protected override void DoCommandAction() { FPGA.FPGATypes.AssertBackendType(FPGA.FPGATypes.BackendType.Vivado); TCLContainer netlistContainer = (TCLContainer)GetNetlistContainer(); TCLDesignHierarchy hier = new TCLDesignHierarchy(); hier.Name = Name; hier.Properties.SetProperty("REF_NAME", Reference, true); netlistContainer.Add(hier); }
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 WritePins(TCLContainer nlc) { m_sw.WriteLine("#########################################################################"); m_sw.WriteLine("# pins"); m_sw.WriteLine("#########################################################################"); m_sw.WriteLine(""); int pinCount = 0; foreach (TCLPin pin in nlc.Pins) { m_sw.WriteLine("# pin " + pinCount++); string name = pin.Instance.Name + "/" + pin.Properties.GetValue("REF_PIN_NAME"); m_sw.WriteLine("create_pin -direction " + pin.Properties.GetValue("DIRECTION") + " " + name); m_sw.WriteLine("connect_net -net [get_nets " + pin.Net.Name + "] -objects [get_pins " + name + "]"); } }
private void WriteHeader(TCLContainer nlc, StreamWriter sw) { sw.WriteLine("#########################################################################"); sw.WriteLine("# this TCL script is generated by GoAhead, the script assembles a netlist"); sw.WriteLine("#########################################################################"); sw.WriteLine("#"); sw.WriteLine("# current device is " + FPGA.FPGA.Instance.DeviceName); sw.WriteLine("# * " + nlc.InstanceCount + " primitives"); sw.WriteLine("# * " + nlc.NetCount + " nets"); sw.WriteLine("# * " + nlc.Pins.Count() + " pins"); sw.WriteLine("#"); sw.WriteLine("#########################################################################"); sw.WriteLine("# instances"); sw.WriteLine("#########################################################################"); sw.WriteLine(""); }
private void CutOffVivado() { TCLContainer nlc = (TCLContainer)GetNetlistContainer(); int netsDone = 0; foreach (TCLNet net in nlc.Nets) { ProgressInfo.Progress = (int)((double)netsDone++ / (double)nlc.NetCount * 100); // only flatten in we will really remove something, otherwise keep the tree structure to save processing later if (net.RoutingTree.GetAllRoutingNodes().Any(n => !n.VirtualNode && TileSelectionManager.Instance.IsSelected(n.Tile))) { net.FlattenNet(); net.Remove(node => !node.VirtualNode && TileSelectionManager.Instance.IsSelected(node.Tile)); } } nlc.Remove(inst => Remove(inst)); }
private void WriteNets(TCLContainer nlc) { m_sw.WriteLine("#########################################################################"); m_sw.WriteLine("# nets"); m_sw.WriteLine("#########################################################################"); m_sw.WriteLine(""); int netCount = 0; foreach (TCLNet net in nlc.Nets) { if (net.NodeNet) { net.UnflattenNet(); } m_sw.WriteLine("# net " + netCount++); if ((netCount % 1000) == 0) { m_sw.WriteLine("puts " + netCount); } m_sw.WriteLine("remove_net -quiet " + net.Name); m_sw.WriteLine("create_net " + net.Name); foreach (NetPin np in net.NetPins) { string direction = np is NetOutpin ? "OUT" : "IN"; m_sw.WriteLine("create_pin -direction " + direction + " " + np.InstanceName + "/" + np.SlicePort); } foreach (NetPin np in net.NetPins) { m_sw.WriteLine("connect_net -net " + net.Name + " -objects " + "[get_pins " + np.InstanceName + "/" + np.SlicePort + "]"); } // insert the ROUTE property m_sw.WriteLine(net.GetTCLRouting()); // we can not set "empty" values foreach (TCLProperty prop in net.Properties.Where(p => !string.IsNullOrEmpty(p.Value) && !p.ReadOnly)) { string value = prop.Value.Contains(" ") ? ("\"" + prop.Value + "\"") : prop.Value; m_sw.WriteLine("set_property " + prop.Name + " " + value + " [get_nets " + net.Name + "]"); } //this.m_sw.WriteLine("set_property IS_ROUTE_FIXED TRUE [get_nets " + net.Name + "]"); m_sw.WriteLine(net.FooterComment); } }
protected override void DoCommandAction() { // Vivado only FPGATypes.AssertBackendType(FPGATypes.BackendType.Vivado); TCLContainer nlc = (TCLContainer)GetNetlistContainer(); bool closeStream = false; if (m_sw == null) { // do not close external stream closeStream = true; m_sw = new StreamWriter(FileName, false); } WriteHeader(nlc, m_sw); if (IncludeLinkDesignCommand) { //this.m_sw.WriteLine("link_design -name empty_netlist -part " + FPGA.FPGA.Instance.DeviceName); } // eingelesen aus Netzliste (also von Vivado erstellt!) genrieren (brauchen wir erstmal nicht, nur fuer eigene instanzen ggf neu Hierstufen ienziehen, siehe create_cell) //this.WriteHierarchyCells(nlc); WriteInstances(nlc); //this.WritePins(nlc); ////this.WritePorts(nlc); WriteNets(nlc); m_sw.WriteLine(""); m_sw.WriteLine("# end of file"); if (closeStream) { m_sw.Close(); } }
private void WriteInstances(TCLContainer nlc) { int instanceCount = 0; // GDN currnently only blockers re supported, overwrok twhen placing netlist!!! foreach (TCLInstance inst in nlc.Instances.Where(i => ((TCLInstance)i).BELType.Equals("GND"))) { m_sw.WriteLine("# instance " + instanceCount++); if (!string.IsNullOrEmpty(inst.BELType) && inst.OmitPlaceCommand) { // Used by blocker m_sw.WriteLine("create_cell -reference " + inst.BELType + " " + inst.Name); } else { m_sw.WriteLine("create_cell -reference " + inst.Properties.GetValue("REF_NAME") + " " + inst.Name); string belName = inst.Properties.GetValue("BEL"); belName = belName.Remove(0, belName.IndexOf('.') + 1); //this.m_sw.WriteLine("place_cell " + inst.Name + " " + inst.SliceName + "/" + belName); bool wrapCatch = inst.Properties.GetValue("REF_NAME").Equals("IBUF") || inst.Properties.GetValue("REF_NAME").Equals("OBUFT"); // we can not set "empty" values, e.g., "set_property ASYNC_REG [get_sites IOB_X0Y1]" foreach (TCLProperty prop in inst.Properties.Where(p => !string.IsNullOrEmpty(p.Value) && !p.ReadOnly && !ExcludedProperties.Contains(p.Name))) { string prefix = wrapCatch ? "catch {" : ""; string suffix = wrapCatch ? "}" : ""; string value = prop.Value.Contains(" ") ? ("\"" + prop.Value + "\"") : prop.Value; m_sw.WriteLine(prefix + "set_property " + prop.Name + " " + value + " [get_cells " + inst.Name + "]" + suffix); } } m_sw.WriteLine(""); } }
private void RelocateInstancesForTCL(LibraryElement libElement, Tile anchorCLB, TCLContainer netlistContainer) { foreach (Tuple <Instance, Tile> tileSliceTupel in libElement.GetInstanceTiles(anchorCLB, libElement)) { TCLInstance newInstance = new TCLInstance((TCLInstance)tileSliceTupel.Item1); // change LOC property and the other fields carries out the actual relocation Slice targetSlice = tileSliceTupel.Item2.Slices[(int)newInstance.SliceNumber]; newInstance.Properties.SetProperty("LOC", targetSlice.SliceName, false); if (InsertPrefix) { newInstance.Name = InstanceName + "_" + newInstance.Name; // do not use / to avoid creating a new hierarchy for which w do not have a refernce cell } newInstance.SliceName = targetSlice.SliceName; newInstance.SliceType = targetSlice.SliceType; newInstance.SliceNumber = targetSlice.ContainingTile.GetSliceNumberByName(targetSlice.SliceName); newInstance.TileKey = targetSlice.ContainingTile.TileKey; newInstance.Location = targetSlice.ContainingTile.Location; newInstance.LocationX = targetSlice.ContainingTile.LocationX; newInstance.LocationY = targetSlice.ContainingTile.LocationY; newInstance.OmitPlaceCommand = true; // TODO we only support GND primitves, overwork this when placing module netlistContainer.Add(newInstance); } }
protected override void DoCommandAction() { TCLContainer nlc = new TCLContainer("VivadoLibraryElement"); DesignParser parser = DesignParser.CreateDesignParser(FileName); try { parser.ParseDesign(nlc, this); } catch (Exception e) { throw new ArgumentException("Error during parsing the design " + FileName + ": " + e.Message + ". Are you trying to open the design on the correct device?"); } LibraryElement libElement = new LibraryElement(); libElement.VivadoConnectionPrimitive = false; libElement.PrimitiveName = Path.GetFileNameWithoutExtension(FileName); libElement.Containter = nlc; libElement.Name = Path.GetFileNameWithoutExtension(FileName); libElement.LoadCommand = ToString(); libElement.ResourceShape = new Shape(); foreach (Instance inst in nlc.Instances) { libElement.ResourceShape.Add(inst.Location); } // X Y coordinates int minX = nlc.Instances.Select(i => i.TileKey.X).Min(); int maxX = nlc.Instances.Select(i => i.TileKey.X).Max(); int minY = nlc.Instances.Select(i => i.TileKey.Y).Min(); int maxY = nlc.Instances.Select(i => i.TileKey.Y).Max(); // get covering rectangle IEnumerable <Tile> rectangle = from tile in FPGA.FPGA.Instance.GetAllTiles() where (IdentifierManager.Instance.IsMatch(tile.Location, IdentifierManager.RegexTypes.CLB) || IdentifierManager.Instance.IsMatch(tile.Location, IdentifierManager.RegexTypes.BRAM) || IdentifierManager.Instance.IsMatch(tile.Location, IdentifierManager.RegexTypes.DSP)) && tile.TileKey.X >= minX && tile.TileKey.X <= maxX && tile.TileKey.Y >= minY && tile.TileKey.Y <= maxY select tile; // Row Column int minRX = rectangle.Select(t => t.LocationX).Min(); int maxCY = rectangle.Select(t => t.LocationY).Max(); IEnumerable <Tile> possibleAnchors = from tile in rectangle where tile.LocationX == minRX && tile.LocationY == maxCY select tile; Tile anchor = possibleAnchors.OrderBy(t => t.TileKey.X).FirstOrDefault(); if (anchor == null) { throw new ArgumentException("No upper left tile of either type CLB, DSP or BRAM found. Can not derive any anchor."); } libElement.ResourceShape.Anchor.AnchorTileLocation = anchor.Location; libElement.ResourceShape.Anchor.AnchorLocationX = anchor.LocationX; libElement.ResourceShape.Anchor.AnchorLocationY = anchor.LocationY; libElement.ResourceShape.Anchor.AnchorSliceNumber = 0; libElement.ResourceShape.Anchor.AnchorSliceName = anchor.Slices[0].SliceName; Objects.Library.Instance.Add(libElement); }