/// <summary>
        /// Copy constructor
        /// </summary>
        /// <param name="other"></param>
        public TCLRoutingTree(TCLRoutingTree other)
        {
            if (other == null)
            {
                return;
            }
            if (other.Root == null)
            {
                return;
            }

            Root = new TCLRoutingTreeNode(other.Root);

            Queue <Tuple <TCLRoutingTreeNode, TCLRoutingTreeNode> > pairs = new Queue <Tuple <TCLRoutingTreeNode, TCLRoutingTreeNode> >();

            pairs.Enqueue(new Tuple <TCLRoutingTreeNode, TCLRoutingTreeNode>(Root, other.Root));

            while (pairs.Count > 0)
            {
                Tuple <TCLRoutingTreeNode, TCLRoutingTreeNode> next = pairs.Dequeue();
                for (int i = 0; i < next.Item2.Children.Count; i++)
                {
                    next.Item1.Children[i] = new TCLRoutingTreeNode(next.Item2.Children[i]);
                    pairs.Enqueue(new Tuple <TCLRoutingTreeNode, TCLRoutingTreeNode>(next.Item1.Children[i], next.Item2.Children[i]));
                }
            }
        }
Esempio n. 2
0
        private void ToTCL(TCLRoutingTreeNode node, StringBuilder buffer)
        {
            if (node == null)
            {
                buffer.Append("{}");
                return;
            }

            // the first two node do need any tabs
            if (node.Depth >= 2)
            {
                buffer.AppendLine(@" \");
                buffer.Append(string.Concat(Enumerable.Repeat("\t", node.Depth)));
            }

            // do not insert braces on last branch
            bool openBranch = node.Parent == null ?
                              false : node.Parent.Children.Count > 1 && !node.Equals(node.Parent.Children[node.Parent.Children.Count - 1]);

            if (openBranch)
            {
                buffer.Append("{");
            }

            // the node itself
            buffer.Append(node.Port.Name + (node.Children.Count == 0 ? "" : " "));

            // the node has leaves only -> dump them without recursion
            if (node.Children.Count > 0 && node.Children.All(n => n.Children.Count == 0))
            {
                for (int i = 0; i < node.Children.Count - 1; i++)
                {
                    buffer.Append("{" + node.Children[i].Port.Name + "}");
                    if (i % 5 == 0 && i > 0)
                    {
                        buffer.AppendLine(@"\");
                        buffer.Append(string.Concat(Enumerable.Repeat("\t", node.Depth + 2)));
                    }
                }
                // last branch goes without braces
                buffer.Append(node.Children[node.Children.Count - 1].Port.Name);
            }
            else
            {
                // the node has children which have children in turn -> recursion
                foreach (TCLRoutingTreeNode child in node.Children)
                {
                    ToTCL(child, buffer);
                }
            }

            if (openBranch)
            {
                buffer.Append("}");
            }
        }
Esempio n. 3
0
        public void UnflattenNet()
        {
            List <TCLRoutingTreeNode> nodeQueue = new List <TCLRoutingTreeNode>(RoutingTree.Root.Children);
            NetOutpin          outPin           = (NetOutpin)NetPins.First(np => np is NetOutpin);
            Tile               rootTile         = FPGA.FPGA.Instance.GetTile(outPin.TileName);
            TCLRoutingTreeNode newRoot          = nodeQueue.FirstOrDefault(n =>
                                                                           n.Tile.Location.Equals(rootTile.Location) &&
                                                                           rootTile.GetSliceByName(outPin.SliceName).PortMapping.IsSliceOutPort(outPin.SlicePort));

            nodeQueue.Remove(newRoot);

            NodeNet          = false;
            RoutingTree.Root = newRoot;
            // try to assign each node to parent
            while (nodeQueue.Count > 0)
            {
                foreach (TCLRoutingTreeNode node in RoutingTree.GetAllRoutingNodes())
                {
                    bool addedNodes = false;
                    // stay on tile
                    TCLRoutingTreeNode nodeOnThisTile = nodeQueue.Find(n =>
                                                                       n.Tile.Location.Equals(node.Tile.Location) &&
                                                                       n.Tile.SwitchMatrix.Contains(node.Port, n.Port));
                    if (nodeOnThisTile != null)
                    {
                        node.Children.Add(nodeOnThisTile);
                        nodeQueue.Remove(nodeOnThisTile);
                        addedNodes = true;
                        break;
                    }

                    // leave tile
                    foreach (Location loc in Navigator.GetDestinations(node.Tile, node.Port))
                    {
                        // look for next hop on loc.Tile
                        TCLRoutingTreeNode nodeOnOtherTile = nodeQueue.Find(n =>
                                                                            n.Tile.Location.Equals(loc.Tile.Location) &&
                                                                            n.Tile.SwitchMatrix.Contains(loc.Pip, n.Port));
                        if (nodeOnOtherTile != null)
                        {
                            node.Children.Add(nodeOnOtherTile);
                            nodeQueue.Remove(nodeOnOtherTile);
                            addedNodes = true;
                            break;
                        }
                    }
                    if (addedNodes)
                    {
                        break;
                    }
                }
            }
        }
Esempio n. 4
0
        public override bool Equals(object obj)
        {
            if (!(obj is TCLRoutingTreeNode))
            {
                return(false);
            }
            TCLRoutingTreeNode other = (TCLRoutingTreeNode)obj;

            // TODO compare more?
            return
                (other.Tile.Location.Equals(Tile.Location) &&
                 other.Port.NameKey == Port.NameKey);
        }
Esempio n. 5
0
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="other"></param>
 public TCLRoutingTreeNode(TCLRoutingTreeNode other)
 {
     Port     = other.Port;
     Children = new Children(other.Children);
     foreach (TCLRoutingTreeNode child in Children)
     {
         child.Parent = this;
     }
     Children.Parent = this;
     Parent          = other.Parent == null? null : new TCLRoutingTreeNode((TCLRoutingTreeNode)other.Parent);
     Tile            = other.Tile;
     VirtualNode     = other.VirtualNode;
 }
Esempio n. 6
0
        private void SetTiles(TCLRoutingTreeNode node, Tile tile, Command caller)
        {
            foreach (TCLRoutingTreeNode child in node.Children)
            {
                child.Tile = tile;
                bool destinationsFound      = false;
                IEnumerable <Location> locs = Navigator.GetDestinations(tile.Location, child.Port.Name);

                if (locs.Count() == 1)
                {
                    SetTiles(child, locs.First().Tile, caller);
                    destinationsFound = true;
                }
                else if (locs.Count() > 1)
                {
                    foreach (Location l in locs)
                    {
                        bool pathCanContinue = true;
                        foreach (TCLRoutingTreeNode c in node.Children)
                        {
                            if (!l.Tile.SwitchMatrix.GetDrivenPorts(l.Pip).Contains(c.Port))
                            {
                                pathCanContinue = false;
                            }
                        }
                        if (pathCanContinue)
                        {
                            SetTiles(child, l.Tile, caller);
                            destinationsFound = true;
                            break;
                        }
                    }

                    /*
                     * Wenn es mehrere loc gibt, dann nimm die, von dessen loc.Pip aus die/der child.children erreichbar sind
                     * Wenn es davon mehrer gibt --> Fehler
                     * if (!child.Port.Name.StartsWith("IMUX") && !child.Port.Name.StartsWith("CLK"))
                     * {
                     *
                     * }
                     * caller.OutputManager.WriteWarning("Path is not unique, branching from node " + child);
                     * */
                }

                if (!destinationsFound)
                {
                    SetTiles(child, tile, caller);
                }
            }
        }
        public IEnumerable <TCLRoutingTreeNode> GetAllRoutingNodes(TCLRoutingTreeNode root)
        {
            // nothing to return in case of empty routing
            if (root != null)
            {
                yield return(root);

                foreach (TCLRoutingTreeNode child in root.Children)
                {
                    foreach (TCLRoutingTreeNode other in GetAllRoutingNodes(child))
                    {
                        yield return(other);
                    }
                }
            }
        }
Esempio n. 8
0
        public void SetTiles(Command caller)
        {
            // no routing
            if (m_routingTree == null)
            {
                return;
            }
            // no routing
            if (m_routingTree.Root == null)
            {
                return;
            }

            if (m_routingTree.Root.VirtualNode)
            {
                foreach (TCLRoutingTreeNode child in m_routingTree.Root.Children)
                {
                    if (child.Tile == null)
                    {
                        throw new ArgumentException("Can not set tiles for virtual node with child " + child + " in " + Name);
                    }
                    SetTiles(child, child.Tile, caller);
                }
            }
            else
            {
                // no start point
                if (OutpinInstance == null)
                {
                    throw new ArgumentException("Can not set tiles due to missing geometrical information in " + Name);
                }
                else
                {
                    Tile t = FPGA.FPGA.Instance.GetTile(OutpinInstance.TileKey);
                    TCLRoutingTreeNode n = m_routingTree.Root;

                    n.Tile = t;
                    SetTiles(n, t, caller);
                }
            }
        }
Esempio n. 9
0
        public void FlattenNet()
        {
            // we do not need to overwrite TCLRoutingTree (which is only s very flat class)
            TCLRoutingTreeNode newRoot = new TCLRoutingTreeNode(null, null);

            newRoot.VirtualNode = true;
            // we can ignore virtual nodes as the new root will be the virtual new node
            foreach (TCLRoutingTreeNode node in RoutingTree.GetAllRoutingNodes().Where(n => !n.VirtualNode))
            {
                newRoot.Children.Add(node);
                node.Parent = newRoot;
            }

            // clear children after iterating over GetAllRoutingNodes, otherwise this will change the result fromGetAllRoutingNodes
            foreach (TCLRoutingTreeNode node in newRoot.Children)
            {
                node.Children.Clear();
            }

            NodeNet          = true;
            RoutingTree.Root = newRoot;
        }
Esempio n. 10
0
        private void ParseRoutingTree(string line, ref TCLRoutingTreeNode root)
        {
            int                i       = 0;
            int                braces  = 0;
            int                start   = 0;
            string             buffer  = "";
            TCLRoutingTreeNode current = root;

            while (i < line.Length)
            {
                switch (line[i])
                {
                case ' ':
                    if (!string.IsNullOrEmpty(buffer))
                    {
                        // buffer is either something like INT_L_X26Y7/VCC_WIRE or EE2BEG0
                        TCLRoutingTreeNode node;
                        string             parameter = buffer;
                        int split = buffer.IndexOf('/');
                        if (split > 0)
                        {
                            string tileName = buffer.Substring(0, split);
                            string portName = buffer.Substring(split + 1, buffer.Length - split - 1);
                            node = new TCLRoutingTreeNode(FPGA.FPGA.Instance.GetTile(tileName), new Port(portName));
                        }
                        else
                        {
                            node = new TCLRoutingTreeNode(new Port(buffer));
                        }
                        node.Parent = current;
                        // if we create the root node, current is null
                        if (root == null)
                        {
                            root = node;
                        }
                        else
                        {
                            current.Children.Add(node);
                        }
                        current = node;
                        buffer  = "";
                    }
                    break;

                case '(':
                    // read everything up to closing bracket
                    start = i;
                    while (i < line.Length)
                    {
                        if (line[i] == ')')
                        {
                            if (root == null)
                            {
                                ParseRoutingTree(line.Substring(start + 1, i - start - 1), ref root);
                            }
                            else
                            {
                                ParseRoutingTree(line.Substring(start + 1, i - start - 1), ref current);
                            }
                            break;
                        }
                        else
                        {
                            i++;
                        }
                    }
                    break;

                case '{':
                    if (braces != 0)
                    {
                        int subtreeBraces = 0;
                        start = i;
                        // extract substree, e.g., { .. {}}
                        while (i < line.Length)
                        {
                            switch (line[i])
                            {
                            case '{':
                                subtreeBraces++;
                                break;

                            case '}':
                                subtreeBraces--;
                                break;

                            default:
                                break;
                            }
                            if (subtreeBraces == 0)
                            {
                                ParseRoutingTree(line.Substring(start, i - start + 1), ref current);
                                // i++ done in outer loop
                                break;
                            }
                            else
                            {
                                i++;
                            }
                        }
                    }
                    else
                    {
                        braces++;
                    }
                    break;

                case '}':
                    braces--;
                    break;

                default:
                    buffer += line[i];
                    break;
                }
                i++;
            }
            if (braces != 0)
            {
                throw new ArgumentException("Incomplete routing tree found: " + line);
            }
        }
Esempio n. 11
0
        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();
        }