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])); } }
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); }
/// <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"); } }
public void Add(LibraryElement other) { m_others.Add(other); }
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); }