コード例 #1
0
        public void Add(LibraryElement element)
        {
            if (Contains(element.Name))
            {
                throw new ArgumentException("A macro named " + element.Name + " is already part of the library");
            }

            m_macros.Add(element);
        }
        public IEnumerable <Tuple <Tile, Slice> > GetAllUsedSlices()
        {
            LibraryElement libElement = Library.Instance.GetElement(LibraryElementName);

            Tile anchor = FPGA.FPGA.Instance.GetTile(AnchorLocation);

            foreach (Tuple <Instance, Tile> instanceTileTupel in libElement.GetInstanceTiles(anchor, libElement))
            {
                // placement of the current instance;
                Tile targetTile = instanceTileTupel.Item2;

                yield return(new Tuple <Tile, Slice>(targetTile, targetTile.Slices[(int)instanceTileTupel.Item1.SliceNumber]));
            }
        }
コード例 #3
0
        public static List <Tile> GetPossibleLibraryElementPlacements(string libraryElementName)
        {
            List <Tile> possiblePlacements = new List <Tile>();

            LibraryElement libElement = Library.Instance.GetElement(libraryElementName);

            foreach (Tile anchor in FPGA.FPGA.Instance.GetAllTiles().Where(t => IdentifierManager.Instance.IsMatch(t.Location, IdentifierManager.RegexTypes.CLB)))
            {
                StringBuilder errorList      = null;
                bool          validPlacement = CheckLibraryElementPlacement(anchor, libElement, out errorList);
                if (validPlacement)
                {
                    possiblePlacements.Add(anchor);
                }
            }

            return(possiblePlacements);
        }
コード例 #4
0
        /// <summary>
        /// Return tupel of an XDLInstance and the tile where the instance will be placed based on the given placementAnchor
        /// </summary>
        /// <returns></returns>
        public IEnumerable <Tuple <Instance, Tile> > GetInstanceTiles(Tile anchor, LibraryElement libElement)
        {
            if (FPGA.FPGA.Instance.BackendType == FPGATypes.BackendType.ISE || (FPGA.FPGA.Instance.BackendType == FPGATypes.BackendType.Vivado && !libElement.VivadoConnectionPrimitive))
            {
                foreach (Instance inst in Containter.Instances)
                {
                    string targetLocation = "";
                    bool   success        = GetTargetLocation(inst.Location, anchor, out targetLocation);

                    if (success)
                    {
                        Tile targetTile = FPGA.FPGA.Instance.GetTile(targetLocation);
                        yield return(new Tuple <Instance, Tile>(inst, targetTile));
                    }
                    else
                    {
                        throw new ArgumentException("Could not relocate " + inst.Location + " from anchor " + anchor);
                    }
                }
            }
            else if (FPGA.FPGA.Instance.BackendType == FPGATypes.BackendType.Vivado && libElement.VivadoConnectionPrimitive)
            {
                TCLInstance inst = new TCLInstance();
                inst.SliceNumber      = SliceNumber;
                inst.SliceName        = anchor.Slices[SliceNumber].SliceName;
                inst.Location         = anchor.Location;
                inst.LocationX        = anchor.LocationX;
                inst.LocationY        = anchor.LocationY;
                inst.SliceType        = anchor.Slices[SliceNumber].SliceType;
                inst.Name             = anchor.Location;
                inst.TileKey          = anchor.TileKey;
                inst.OmitPlaceCommand = true;
                inst.BELType          = libElement.PrimitiveName;
                Tuple <Instance, Tile> result = new Tuple <Instance, Tile>(inst, anchor);
                yield return(result);
            }
            else
            {
                throw new ArgumentException("Unsupported branch in GetInstanceTiles");
            }
        }
コード例 #5
0
 public void Add(LibraryElement other)
 {
     m_others.Add(other);
 }
コード例 #6
0
        public static bool CheckLibraryElementPlacement(Tile anchor, LibraryElement libElement, out StringBuilder errorList)
        {
            errorList = new StringBuilder();
            int errorCountLength = 512;

            // check relocation
            bool relocationPossible = libElement.IsRelocationPossible(anchor, out errorList);

            if (!relocationPossible)
            {
                // if relocation fails, stop trying
                errorList.AppendLine("Error during relocation. Can not relocate all tiles. Does the module footprint match");
                return(false);
            }

            foreach (Tuple <Instance, Tile> instanceTile in libElement.GetInstanceTiles(anchor, libElement))
            {
                if (errorList.Length > errorCountLength)
                {
                    break;
                }

                if (instanceTile.Item1 == null && instanceTile.Item2 == null)
                {
                    errorList.AppendLine("Left FPGA during macro placement form anchor (error during relocation)");
                    continue;
                }

                Tile targetTile = instanceTile.Item2;

                bool twoCLBS = IdentifierManager.Instance.IsMatch(targetTile.Location, IdentifierManager.RegexTypes.CLB) &&
                               IdentifierManager.Instance.IsMatch(instanceTile.Item1.Location, IdentifierManager.RegexTypes.CLB);

                // target tile type must match: remove digits from location string and expect equality
                string targetLocationWithoutDigits = Regex.Replace(targetTile.Location, @"\d", "");
                string instLocationWithoutDigits   = Regex.Replace(instanceTile.Item1.Location, @"\d", "");
                if (!targetLocationWithoutDigits.Equals(instLocationWithoutDigits) && !twoCLBS)
                {
                    errorList.AppendLine("Tile type mismatch. Can not place " + instanceTile.Item1.Location + " at " + targetTile.Location);
                }

                if (instanceTile.Item1.SliceNumber < targetTile.Slices.Count)
                {
                    Slice targetSlice = targetTile.Slices[(int)instanceTile.Item1.SliceNumber];

                    string requiredSliceType = instanceTile.Item1.SliceType;
                    string targetSliceType   = targetSlice.SliceType;

                    // slice type must be compatible
                    // compare parameterizable slice types
                    bool sliceTypesAreCompatible = SliceCompare.Instance.Matches(requiredSliceType, targetSliceType);

                    // if not match was found (e.g. due to missing or incomplete init.goa), try the hardcaoded comparsion
                    if (!sliceTypesAreCompatible)
                    {
                        if (requiredSliceType.Equals(targetSliceType))
                        {
                            sliceTypesAreCompatible = true;
                        }
                        else if (requiredSliceType.Equals("SLICEX") && targetSliceType.Equals("SLICEX"))
                        {
                            sliceTypesAreCompatible = true;
                        }
                        else if (requiredSliceType.Equals("SLICEX") && targetSliceType.Equals("SLICEM"))
                        {
                            sliceTypesAreCompatible = true;
                        }
                        else if (requiredSliceType.Equals("SLICEX") && targetSliceType.Equals("SLICEL"))
                        {
                            sliceTypesAreCompatible = true;
                        }
                        else if (requiredSliceType.Equals("SLICEL") && targetSliceType.Equals("SLICEX"))
                        {
                            sliceTypesAreCompatible = false;
                        }
                        else if (requiredSliceType.Equals("SLICEL") && targetSliceType.Equals("SLICEM"))
                        {
                            sliceTypesAreCompatible = true;
                        }
                        else if (requiredSliceType.Equals("SLICEL") && targetSliceType.Equals("SLICEL"))
                        {
                            sliceTypesAreCompatible = true;
                        }
                        else if (requiredSliceType.Equals("SLICEM") && targetSliceType.Equals("SLICEX"))
                        {
                            sliceTypesAreCompatible = false;
                        }
                        else if (requiredSliceType.Equals("SLICEM") && targetSliceType.Equals("SLICEM"))
                        {
                            sliceTypesAreCompatible = true;
                        }
                        else if (requiredSliceType.Equals("SLICEM") && targetSliceType.Equals("SLICEL"))
                        {
                            sliceTypesAreCompatible = false;
                        }
                        else if (targetSliceType.StartsWith(requiredSliceType))
                        {
                            sliceTypesAreCompatible = true;
                        }
                    }
                    ;
                    if (!sliceTypesAreCompatible)
                    {
                        errorList.AppendLine("Incompatible Slice Type found: Required is " + requiredSliceType + " but found " + targetSliceType + " at " + targetTile.Location);
                    }

                    // check if slice is still free
                    if (targetSlice.Usage != FPGATypes.SliceUsage.Free)
                    {
                        errorList.AppendLine("Slice " + targetSlice + " is used already");
                    }
                }
                else
                {
                    errorList.AppendLine("Expecting " + (instanceTile.Item1.SliceNumber + 1) + " slices " + targetTile.Location + ". Only found " + targetTile.Slices.Count);
                }
            }

            try
            {
                // check if all ports are free
                foreach (Tuple <Tile, List <Port> > tilePortListTupel in libElement.GetPortsToBlock(anchor))
                {
                    foreach (Port portToBlock in tilePortListTupel.Item2)
                    {
                        if (errorList.Length > errorCountLength)
                        {
                            break;
                        }

                        // Port may not be blocked and must exist
                        if (tilePortListTupel.Item1.IsPortBlocked(portToBlock))
                        {
                            errorList.AppendLine("Port " + portToBlock + " on tile " + tilePortListTupel.Item1.Location + " is used already");
                        }
                        if (!tilePortListTupel.Item1.SwitchMatrix.Contains(portToBlock))
                        {
                            errorList.AppendLine("Port " + portToBlock + " on tile " + tilePortListTupel.Item1.Location + " does not exist");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                errorList.AppendLine(e.Message);
            }

            // error
            return(errorList.Length == 0);
        }