Exemple #1
0
        private List <Signal> GetSignals(FPGA.FPGATypes.InterfaceDirection dir, int column, string mode)
        {
            List <Signal> inputs = Objects.InterfaceManager.Instance.GetFlatSignalList(
                s => s.SignalMode.Equals(mode) && s.Column == column &&
                s.PartialRegion.Equals(IslandName) && s.SignalDirection.Equals(dir));

            return(inputs);
        }
Exemple #2
0
        private Tile MoveAnchorToNextColumn(FPGA.FPGATypes.InterfaceDirection dir, Tile currentAnchor)
        {
            switch (dir)
            {
            case FPGATypes.InterfaceDirection.East: { currentAnchor = Navigator.GetNextCLB(currentAnchor, 0, 1); break; }     // go left

            case FPGATypes.InterfaceDirection.West: { currentAnchor = Navigator.GetNextCLB(currentAnchor, 0, 1); break; }     // go left

            default: { throw new ArgumentException("Can not handle direction " + dir); }
            }
            return(currentAnchor);
        }
Exemple #3
0
 /// <summary>
 /// Check that all passed tiles ar in (stati) or out of (modul) the partial area
 /// </summary>
 /// <param name="dir"></param>
 /// <param name="macroTiles"></param>
 private void CheckMacroTiles(FPGA.FPGATypes.InterfaceDirection dir, List <Tile> macroTiles)
 {
     foreach (Tile anchor in macroTiles)
     {
         if (BuildTarget == Target.Static)
         {
             if (!TileSelectionManager.Instance.IsUserSelected(anchor.TileKey, IslandName))
             {
                 throw new ArgumentException("The interface of " + IslandName + " is too large to be placed in the selected area (" + dir + ")");
             }
         }
         if (BuildTarget == Target.Module)
         {
             if (TileSelectionManager.Instance.IsUserSelected(anchor.TileKey, IslandName))
             {
                 throw new ArgumentException("The interface of " + IslandName + " is too large to be placed in the selected area (" + dir + ")");
             }
         }
     }
 }
Exemple #4
0
        private List <Tile> GetAnchors(FPGA.FPGATypes.InterfaceDirection dir, int columns, bool streaming, out List <Tile> tilesToReleaseWiresOn)
        {
            List <Tile> result = new List <Tile>();

            tilesToReleaseWiresOn = new List <Tile>();

            FPGATypes.Placement placement = 0;
            switch (dir)
            {
            case FPGATypes.InterfaceDirection.East: { placement = FPGATypes.Placement.UpperRight; break; }

            case FPGATypes.InterfaceDirection.West: { placement = FPGATypes.Placement.UpperLeft; break; }

            default: { throw new ArgumentException("Can not hanlde direction " + dir); }
            }

            Tile anchor = TileSelectionManager.Instance.GetUserSelectedTile(
                IdentifierManager.Instance.GetRegex(IdentifierManager.RegexTypes.CLB),
                IslandName,
                placement);

            // move this way to collect anchors for columns
            int xIncrement = 0;
            int yIncrement = 0;

            switch (dir)
            {
            case FPGATypes.InterfaceDirection.East: { xIncrement = -1; yIncrement = 0; break; }

            case FPGATypes.InterfaceDirection.West: { xIncrement = 1; yIncrement = 0; break; }
            }
            xIncrement *= m_columnStepWidth;
            yIncrement *= m_columnStepWidth;

            // for module anchors move the anchors out of the partial area
            if (BuildTarget == Target.Module)
            {
                if (m_islandName.Equals("pr5"))
                {
                }

                int xAnchorShift = 0;
                int yAnchorShift = 0;
                switch (dir)
                {
                case FPGATypes.InterfaceDirection.East: { xAnchorShift = 1; yAnchorShift = 0; break; }

                case FPGATypes.InterfaceDirection.West: { xAnchorShift = -1; yAnchorShift = 0; break; }
                }
                xAnchorShift *= m_columnStepWidth;
                yAnchorShift *= m_columnStepWidth;

                // TODO here, we assume double lines
                Tile start = anchor;
                for (int column = 0; column < columns; column++)
                {
                    // besser mit DoubleLine (parameter) von Anker auf den naechsten CLB gehen

                    /*
                     * do
                     * {
                     *  anchor = Search.Navigator.GetNextCLB(anchor, xAnchorShift, yAnchorShift, tilesToReleaseWiresOn);
                     * }
                     * while (Math.Abs(start.LocationX - anchor.LocationX) % 2 != 0);
                     * */
                    anchor = Navigator.GetNextCLB(anchor, xAnchorShift, yAnchorShift, tilesToReleaseWiresOn);
                    anchor = Navigator.GetNextCLB(anchor, xAnchorShift, yAnchorShift, tilesToReleaseWiresOn);
                }
            }

            // first anchor
            result.Add(anchor);
            Tile current = anchor;

            // start with 1 as we have the anchor added already
            for (int column = 1; column < columns; column++)
            {
                current = Navigator.GetNextCLB(current, xIncrement, yIncrement, tilesToReleaseWiresOn);
                result.Add(current);
            }

            // East 0 1 2
            // West 2 1 0 -> Reverse
            if (dir == FPGATypes.InterfaceDirection.East)
            {
                result.Reverse();
            }

            return(result);
        }
Exemple #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="connectionPrimitiveName"></param>
        /// <param name="instance"></param>
        /// <param name="columns"></param>
        /// <param name="maxWiresPerRow"></param>
        /// <param name="prefix">The prefix that can be sued for subsequent AnnotateSignal commands</param>
        /// <returns></returns>
        private List <Command> GetPlacementCommands(FPGA.FPGATypes.InterfaceDirection dir, string connectionPrimitiveName, string instance, int columns, int maxWiresPerRow)
        {
            LibraryElement libElement            = Objects.Library.Instance.GetElement(connectionPrimitiveName);
            List <Tile>    tilesToReleaseWiresOn = null;

            List <Tile> anchors = GetAnchors(dir, columns, false, out tilesToReleaseWiresOn);

            Dictionary <int, List <Signal> > inputsPerColumn  = new Dictionary <int, List <Signal> >();
            Dictionary <int, List <Signal> > outputsPerColumn = new Dictionary <int, List <Signal> >();

            //Console.WriteLine(dir);
            //Console.WriteLine(instance);

            for (int column = 0; column < columns; column++)
            {
                List <Signal> inputs  = GetSignals(dir, column, "in");
                List <Signal> outputs = GetSignals(dir, column, "out");

                // equalize both list with open signals, the signal paramteres are dont care
                while (inputs.Count % maxWiresPerRow != 0 || inputs.Count < outputs.Count)
                {
                    inputs.Add(new Signal("open", "in", dir, IslandName, column));
                }
                while (outputs.Count < inputs.Count)
                {
                    outputs.Add(new Signal("open", "out", dir, IslandName, column));
                }

                inputsPerColumn[column]  = inputs;
                outputsPerColumn[column] = outputs;
            }

            Dictionary <Tile, List <Signal> > inputsOnTile  = new Dictionary <Tile, List <Signal> >();
            Dictionary <Tile, List <Signal> > outputsOnTile = new Dictionary <Tile, List <Signal> >();
            List <Tile> connectionPrimitiveCLBs             = new List <Tile>();

            // 1 collect inputs in this tile

            // iterate row wise
            for (int column = 0; column < columns; column++)
            {
                Tile currentAnchor = anchors[column];
                for (int i = 0; i < inputsPerColumn[column].Count; i += maxWiresPerRow)
                {
                    inputsOnTile.Add(currentAnchor, new List <Signal>());
                    outputsOnTile.Add(currentAnchor, new List <Signal>());
                    connectionPrimitiveCLBs.Add(currentAnchor);

                    for (int j = 0; j < maxWiresPerRow; j++)
                    {
                        Signal input = inputsPerColumn[column][i + j];
                        inputsOnTile[currentAnchor].Add(input);

                        Signal output = outputsPerColumn[column][i + j];
                        outputsOnTile[currentAnchor].Add(output);
                    }

                    currentAnchor = MoveAnchorToNextColumn(dir, currentAnchor);
                }
            }

            CheckMacroTiles(dir, connectionPrimitiveCLBs);

            string prefix = instance + connectionPrimitiveName;
            // do connection primitive instantiation
            List <Command> result = new List <Command>();

            foreach (Tile anchor in connectionPrimitiveCLBs)
            {
                List <Signal> localInputs  = inputsOnTile[anchor];
                List <Signal> localOutputs = outputsOnTile[anchor];

                // do we need to place a macro here
                bool placeMacro = HasNonOpenSignal(localInputs) || HasNonOpenSignal(localOutputs);
                if (!placeMacro)
                {
                    continue;
                }

                // check that the added signal names are all identical
                if (localOutputs.Select(s => s.SignalNameWithoutBraces).Distinct().Count() != 1)
                {
                    throw new ArgumentException("Signal names may only change at a boundary of 4. Check signal " + localInputs[0]);
                }
                if (localInputs.Select(s => s.SignalNameWithoutBraces).Distinct().Count() != 1)
                {
                    throw new ArgumentException("Signal names may only change at a boundary of 4. Check signal " + localOutputs[0]);
                }

                // can we use this tile for placement?
                StringBuilder errorList      = null;
                bool          validPlacement = DesignRuleChecker.CheckLibraryElementPlacement(anchor, libElement, out errorList);
                if (!validPlacement)
                {
                    throw new ArgumentException("Can not place the library element at the desired postion (check the output window)" + errorList.ToString());
                }

                // finally, place the macro
                AddSingleInstantiationByTile addByTile = new AddSingleInstantiationByTile();
                addByTile.AnchorLocation      = anchor.Location;
                addByTile.AutoClearModuleSlot = false;
                addByTile.InstanceName        = prefix + "_" + result.Count;
                addByTile.LibraryElementName  = connectionPrimitiveName;
                if (result.Count == 0)
                {
                    addByTile.Comment = "instantiate a connection primitive at tile " + addByTile.AnchorLocation + ". An expert may want to relocate the instantiations";
                }
                result.Add(addByTile);

                AnnotateSignalNames annotateCmd = new AnnotateSignalNames();
                annotateCmd.InstantiationFilter = "^" + addByTile.InstanceName;

                string inputSource  = BuildTarget == Target.Static ? "I:" : "O:";
                string outputSource = BuildTarget == Target.Static ? "O:" : "I:";
                annotateCmd.PortMapping.Add(inputSource + localInputs[0].SignalNameWithoutBraces + ":external");
                annotateCmd.PortMapping.Add(outputSource + localOutputs[0].SignalNameWithoutBraces + ":external");
                annotateCmd.PortMapping.Add("H:H:internal");
                result.Add(annotateCmd);
            }

            return(result);
        }