public void SetPins() { foreach (TCLRoutingTreeNode node in RoutingTree.GetAllRoutingNodes().Where(n => !n.VirtualNode)) { Tile t = node.Tile; foreach (Slice s in t.Slices) { bool inport = s.PortMapping.IsSliceInPort(node.Port); bool outport = s.PortMapping.IsSliceOutPort(node.Port); if ((inport || outport) && node.Port.Name.Contains('_')) { NetPin pin = null; if (inport) { pin = new NetInpin(); } else { pin = new NetOutpin(); } pin.SlicePort = node.Port.Name.Substring(node.Port.Name.LastIndexOf('_')); pin.InstanceName = s.SliceName; bool pinExistsAlready = NetPins.FirstOrDefault(np => np.InstanceName.Equals(pin.InstanceName) && np.SlicePort.Equals(pin.SlicePort)) != null; if (!pinExistsAlready) { Add(pin); } } } } }
protected override void DoCommandAction() { FPGATypes.AssertBackendType(FPGATypes.BackendType.ISE); NetlistContainer netlistContainer = GetNetlistContainer(); foreach (XDLNet n in netlistContainer.Nets) { foreach (XDLPip pip in n.Pips) { Tile t = FPGA.FPGA.Instance.GetTile(pip.Location); if (!IdentifierManager.Instance.IsMatch(t.Location, IdentifierManager.RegexTypes.CLB)) { continue; } foreach (Slice s in t.Slices) { bool inport = s.PortMapping.IsSliceInPort(new Port(pip.To)); bool outport = s.PortMapping.IsSliceOutPort(new Port(pip.To)); if ((inport | outport) && pip.To.Contains('_')) { NetPin pin = null; if (inport) { pin = new NetInpin(); } else { pin = new NetOutpin(); } string[] atoms = pip.To.Split('_'); pin.SlicePort = atoms[1]; if (netlistContainer.Instances.Any(i => i.SliceName.Equals(s.SliceName))) { // there should be only one instance on the slice XDLInstance inst = (XDLInstance)netlistContainer.Instances.First(i => i.SliceName.Equals(s.SliceName)); pin.InstanceName = inst.Name; } else { pin.InstanceName = s.SliceName; } bool pinExistsAlready = n.NetPins.FirstOrDefault(np => np.InstanceName.Equals(pin.InstanceName) && np.SlicePort.Equals(pin.SlicePort)) != null; if (!pinExistsAlready) { n.Add(pin); } } } } } }
private void ProcessNextNetLine(char[] buffer, int size, XDLNet net) { string[] atoms = null; try { atoms = m_splitNetLineWhiteSpaceOnly.Split(new string(buffer, 0, size)); } catch { Console.WriteLine(size); Console.WriteLine(buffer); Console.WriteLine(net); } for (int i = 0; i < atoms.Length; i++) { if (atoms[i].Equals("pip")) { string location = atoms[i + 1]; string from = atoms[i + 2]; string op = atoms[i + 3]; string to = atoms[i + 4].Replace(",", ""); XDLPip pip = new XDLPip(location, from, op, to); net.Add(pip); return; } else if (atoms[i].Equals("inpin")) { NetInpin inpin = new NetInpin(); inpin.InstanceName = atoms[i + 1]; inpin.SlicePort = atoms[i + 2]; net.Add(Trim(inpin)); return; } else if (atoms[i].Equals("outpin")) { NetOutpin outpin = new NetOutpin(); outpin.InstanceName = atoms[i + 1]; outpin.SlicePort = atoms[i + 2]; net.Add(Trim(outpin)); return; } else if (atoms[i].Equals("cfg")) { //net.Config = "cfg "; for (int j = 0; j < size; j++) { net.Config += buffer[j]; } return; } } }
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); }
public override void ParseDesign(NetlistContainer nlc, Command caller) { TCLContainer container = (TCLContainer)nlc; Regex commentRegexp = new Regex(@"^\s*#", RegexOptions.Compiled); StreamReader sr = new StreamReader(m_fileName); FileInfo fi = new FileInfo(m_fileName); long charCount = 0; string line = ""; while ((line = sr.ReadLine()) != null) { //Console.WriteLine(line); if (line.Equals("debug")) { } charCount += line.Length; if (caller.PrintProgress) { caller.ProgressInfo.Progress = (int)((double)charCount / (double)fi.Length * caller.ProgressShare); } if (commentRegexp.IsMatch(line)) { continue; } int length = line.IndexOf('='); string linePrefix = line.Substring(0, length); string[] atoms = line.Split(';'); caller.Watch.Start("switch"); switch (linePrefix) { case "Cell": // BEL=IOB33.INBUF_EN(0),CLASS=cell(1), TCLInstance cellInstance = new TCLInstance(); cellInstance.AddCode(line); foreach (string atom in atoms.Where(a => !string.IsNullOrEmpty(a))) { string atomPrefix; string atomData; bool readOnly; bool property; Decompose(atom, out atomPrefix, out atomData, out readOnly, out property); // store special properties (i.e. name or properties that need ot modified) switch (atomPrefix) { case "NAME": cellInstance.Name = atomData; // flatten hierarchy to ease/enable netlist relocation cellInstance.Name = cellInstance.Name.Replace('/', '_'); break; case "LOC": Slice s = FPGA.FPGA.Instance.GetSlice(atomData); cellInstance.SliceName = s.SliceName; cellInstance.SliceType = s.SliceType; cellInstance.SliceNumber = s.ContainingTile.GetSliceNumberByName(s.SliceName); cellInstance.TileKey = s.ContainingTile.TileKey; cellInstance.Location = s.ContainingTile.Location; cellInstance.LocationX = s.ContainingTile.LocationX; cellInstance.LocationY = s.ContainingTile.LocationY; // we need a name and a location to add the instance break; case "BEL": cellInstance.BELType = atomData.Substring(atomData.LastIndexOf(".") + 1); break; } // Primitive is not a Xilinx primitive property, but denotes a primitive instance in a GoAhead netlist (*.viv_rpt if (property) { cellInstance.Properties.SetProperty(atomPrefix, atomData, readOnly); } } container.Add(cellInstance); break; case "Net": // Net=I_IBUF[0],Routing={},BelPin=SLICE_X20Y6/D6LUT/A5,BelPin=SLICE_X20Y11/C6LUT/A6,BelPin=IOB_X0Y1/INBUF_EN/OUT TCLNet net = new TCLNet("replacedLater"); net.AddCode(line); foreach (string atom in atoms.Where(a => !string.IsNullOrEmpty(a))) { string atomPrefix; string atomData; bool readOnly; bool property; Decompose(atom, out atomPrefix, out atomData, out readOnly, out property); switch (atomPrefix) { case "Net": net.Name = atomData; // flatten hierarchy to ease/enable netlist relocation net.Name = net.Name.Replace('/', '_'); // we need a name to add the net container.Add(net); break; case "Nodes": net.RoutingTree = new TCLRoutingTree(); net.RoutingTree.Root = new TCLRoutingTreeNode(null, null); net.RoutingTree.Root.VirtualNode = true; net.NodeNet = true; string[] nodes = atomData.Split(' '); foreach (string node in nodes) { string nodeTileName = node.Substring(0, node.IndexOf('/')); string nodePortName = node.Substring(node.IndexOf('/') + 1); TCLRoutingTreeNode routingNode = new TCLRoutingTreeNode(FPGA.FPGA.Instance.GetTile(nodeTileName), new Port(nodePortName)); net.RoutingTree.Root.Children.Add(routingNode); } break; case "BelPin": // BelPin=IOB_X0Y1/INBUF_EN/OUT string[] hierarchy = atomData.Split('/'); string sliceName = hierarchy[0]; string belName = hierarchy[1]; string portName = hierarchy[2]; Instance instance = container.GetInstanceBySliceName(sliceName, belName); // inst ist manchmal null, kommt bei ROUTETHROUGH vor, also zb A6 und es wird durch die LUT durchgeroutet Slice slice = FPGA.FPGA.Instance.GetSlice(sliceName); NetPin netPin; if (slice.PortMapping.IsSliceInPort(portName)) { netPin = new NetInpin(); netPin.TileName = slice.ContainingTile.Location; } else if (slice.PortMapping.IsSliceOutPort(portName)) { netPin = new NetOutpin(); net.OutpinInstance = instance; netPin.TileName = slice.ContainingTile.Location; } else { throw new ArgumentException("Cannot resolve direction of bel pin " + portName + " in line " + line); } netPin.InstanceName = instance != null? instance.Name : "unknown instance"; netPin.SliceName = sliceName; netPin.SlicePort = portName; netPin.Code = atomData; net.Add(netPin); break; case "ROUTE": case "FIXED_ROUTE": // we need the property TYPE before we can pasrs the net if (net.Properties.HasProperty("TYPE")) { // parse now net.RoutingTree = new TCLRoutingTree(); if (net.Type == TCLNet.NetType.POWER || net.Type == TCLNet.NetType.GROUND) // TODO more?? { net.RoutingTree.Root = new TCLRoutingTreeNode(null, null); net.RoutingTree.Root.VirtualNode = true; } ParseRoutingTree(atomData, ref net.RoutingTree.Root); } else { // parse later net.SetCode(atomData); } // do not set property ROUTE, as the ROUTE property is generated //net.Properties.SetProperty(atomPrefix, atomData, readOnly); break; case "TYPE": net.Properties.SetProperty(atomPrefix, atomData, readOnly); net.Type = (TCLNet.NetType)Enum.Parse(typeof(TCLNet.NetType), net.Properties.GetValue("TYPE")); if (net.RoutingTree == null) { net.RoutingTree = new TCLRoutingTree(); if (net.Type == TCLNet.NetType.POWER || net.Type == TCLNet.NetType.GROUND) { net.RoutingTree.Root = new TCLRoutingTreeNode(null, null); net.RoutingTree.Root.VirtualNode = true; } ParseRoutingTree(net.GetCode(), ref net.RoutingTree.Root); } break; default: net.Properties.SetProperty(atomPrefix, atomData, readOnly); break; } } break; case "Pin": TCLPin pin = new TCLPin(); pin.AddCode(line); foreach (string atom in atoms.Where(a => !string.IsNullOrEmpty(a))) { string atomPrefix; string atomData; bool readOnly; bool property; Decompose(atom, out atomPrefix, out atomData, out readOnly, out property); switch (atomPrefix) { case "Pin": pin.Name = atomData; container.Add(pin); break; default: pin.Properties.SetProperty(atomPrefix, atomData, readOnly); break; } } break; case "Port": TCLPort port = new TCLPort(); port.AddCode(line); foreach (string atom in atoms.Where(a => !string.IsNullOrEmpty(a))) { string atomPrefix; string atomData; bool readOnly; bool property; Decompose(atom, out atomPrefix, out atomData, out readOnly, out property); switch (atomPrefix) { case "Port": port.ExternalName = atomData; container.Add(port); break; default: port.Properties.SetProperty(atomPrefix, atomData, readOnly); break; } } break; case "Hierarchy": TCLDesignHierarchy hier = new TCLDesignHierarchy(); hier.AddCode(line); foreach (string atom in atoms.Where(a => !string.IsNullOrEmpty(a))) { string atomPrefix; string atomData; bool readOnly; bool property; Decompose(atom, out atomPrefix, out atomData, out readOnly, out property); switch (atomPrefix) { case "Hierarchy": hier.Name = atomData; container.Add(hier); break; default: hier.Properties.SetProperty(atomPrefix, atomData, readOnly); break; } } break; default: throw new ArgumentException("Unexpected netlist element: " + line); } caller.Watch.Stop("switch"); } foreach (TCLNet n in container.Nets) { int pinCount = int.Parse(n.Properties.GetValue("PIN_COUNT")); int flatPinCount = int.Parse(n.Properties.GetValue("FLAT_PIN_COUNT")); if (pinCount != flatPinCount) { } if (pinCount != n.NetPinCount) { //caller.OutputManager.WriteWarning("PIN_COUNT should match the number of BelPins in " + n.Name); } } foreach (TCLNet n in container.Nets) { caller.Watch.Start("SetTiles"); n.SetTiles(caller); caller.Watch.Stop("SetTiles"); caller.Watch.Start("SetPins"); n.SetPins(); caller.Watch.Stop("SetPins"); } sr.Close(); }