private void RelocateInstancesForTCL(LibraryElement libElement, Tile anchorCLB, TCLContainer netlistContainer) { foreach (Tuple <Instance, Tile> tileSliceTupel in libElement.GetInstanceTiles(anchorCLB, libElement)) { TCLInstance newInstance = new TCLInstance((TCLInstance)tileSliceTupel.Item1); // change LOC property and the other fields carries out the actual relocation Slice targetSlice = tileSliceTupel.Item2.Slices[(int)newInstance.SliceNumber]; newInstance.Properties.SetProperty("LOC", targetSlice.SliceName, false); if (InsertPrefix) { newInstance.Name = InstanceName + "_" + newInstance.Name; // do not use / to avoid creating a new hierarchy for which w do not have a refernce cell } newInstance.SliceName = targetSlice.SliceName; newInstance.SliceType = targetSlice.SliceType; newInstance.SliceNumber = targetSlice.ContainingTile.GetSliceNumberByName(targetSlice.SliceName); newInstance.TileKey = targetSlice.ContainingTile.TileKey; newInstance.Location = targetSlice.ContainingTile.Location; newInstance.LocationX = targetSlice.ContainingTile.LocationX; newInstance.LocationY = targetSlice.ContainingTile.LocationY; newInstance.OmitPlaceCommand = true; // TODO we only support GND primitves, overwork this when placing module netlistContainer.Add(newInstance); } }
private void RelocateInstancesForXDL(LibraryElement libElement, Tile anchorCLB, XDLContainer netlistContainer) { // reli foreach (Tuple <Instance, Tile> tileSliceTupel in libElement.GetInstanceTiles(anchorCLB, libElement)) { int sliceNumber = tileSliceTupel.Item1.SliceNumber; Slice slice = tileSliceTupel.Item2.Slices[sliceNumber]; string xdlCode = tileSliceTupel.Item1.ToString(); /* in TODO init.goa auslagern * @"placed.*SLICE_X\d+Y\d+"; * @"placed.*TIEOFF_X\d+Y\d+"; * @"placed.*RAMB16_X\d+Y\d+" * */ if (IdentifierManager.Instance.IsMatch(tileSliceTupel.Item1.Location, IdentifierManager.RegexTypes.CLB)) { // replace placement information in: inst "right" "SLICEX", placed CLEXL_X9Y33 SLICE_X13Y33 string newPlacement = "placed " + tileSliceTupel.Item2.Location + " " + slice.SliceName; string oldPlacement = @"placed.*SLICE_X\d+Y\d+"; xdlCode = Regex.Replace(xdlCode, oldPlacement, newPlacement); } else if (IdentifierManager.Instance.IsMatch(tileSliceTupel.Item1.Location, IdentifierManager.RegexTypes.Interconnect)) { string newPlacement = "placed " + tileSliceTupel.Item2.Location + " " + slice.SliceName; string oldPlacement = @"placed.*TIEOFF_X\d+Y\d+"; xdlCode = Regex.Replace(xdlCode, oldPlacement, newPlacement); } else if (IdentifierManager.Instance.IsMatch(tileSliceTupel.Item1.Location, IdentifierManager.RegexTypes.DSP)) { int underScoreLocation = tileSliceTupel.Item2.Location.IndexOf("_"); string locationPrefix = tileSliceTupel.Item2.Location.Substring(0, underScoreLocation); string newPlacement = "placed " + tileSliceTupel.Item2.Location + " " + slice.SliceName; string oldPlacement = "placed.*" + locationPrefix + @"_X\d+Y\d+.*" + tileSliceTupel.Item1.SliceName; xdlCode = Regex.Replace(xdlCode, oldPlacement, newPlacement); } else if (IdentifierManager.Instance.IsMatch(tileSliceTupel.Item1.Location, IdentifierManager.RegexTypes.BRAM)) { int underScoreLocation = tileSliceTupel.Item2.Location.IndexOf("_"); string locationPrefix = tileSliceTupel.Item2.Location.Substring(0, underScoreLocation); string newPlacement = "placed " + tileSliceTupel.Item2.Location + " " + slice.SliceName; string oldPlacement = "placed.*" + locationPrefix + @"_X\d+Y\d+.*" + tileSliceTupel.Item1.SliceName; //String oldPlacement = @"placed.*RAMB16_X\d+Y\d+"; xdlCode = Regex.Replace(xdlCode, oldPlacement, newPlacement); } if (InsertPrefix) { // insert instance prefix // remove greedy between double quotes MatchCollection matches = Regex.Matches(xdlCode, "(\".*?\")"); string oldInstanceName = matches[0].ToString(); oldInstanceName = Regex.Replace(oldInstanceName, "\"", ""); string newInstanceName = InstanceName + Regex.Replace(oldInstanceName, "\"", ""); // replace both the instance name AND slice configuration xdlCode = xdlCode.Replace("\"" + oldInstanceName, "\"" + newInstanceName); if (IdentifierManager.Instance.IsMatch(tileSliceTupel.Item1.Location, IdentifierManager.RegexTypes.BRAM)) { xdlCode = xdlCode.Replace("RAMB16BWER:" + oldInstanceName, "RAMB16BWER:" + newInstanceName); } // XDL Shape?? xdlCode = xdlCode.Replace("Shape_", InstanceName + "Shape_"); } netlistContainer.AddSliceCodeBlock(xdlCode); } }
protected override void DoCommandAction() { LibraryElement libElement = Objects.Library.Instance.GetElement(LibraryElementName); if (!FPGA.FPGA.Instance.Contains(AnchorLocation)) { throw new ArgumentException("FPGA does not contain location " + AnchorLocation); } Tile anchor = FPGA.FPGA.Instance.GetTile(AnchorLocation); foreach (Tuple <Tile, List <Port> > t in libElement.GetPortsToBlock(anchor)) { t.Item2.ForEach(p => t.Item1.BlockPort(p, Tile.BlockReason.OccupiedByMacro)); } // for ISE we could instantly mark the slices as Macro, but for Vivado we visit the same slice multiple times // store the to be marked slice in here and set their usage to Macro at the END of the command List <Slice> targets = new List <Slice>(); // attach usage to slice foreach (Tuple <Instance, Tile> t in libElement.GetInstanceTiles(anchor, libElement)) { int sliceNumber = t.Item1.SliceNumber; Slice target = t.Item2.Slices[(int)sliceNumber]; switch (FPGA.FPGA.Instance.BackendType) { case FPGATypes.BackendType.ISE: if (target.Usage != FPGATypes.SliceUsage.Free && CheckResources) { throw new ArgumentException("Can not place library element at " + target + " as this slice is already used"); // TODO warum geht das beim BRAM nicht } targets.Add(target); break; case FPGATypes.BackendType.Vivado: // in Vivado we set usage at the bel level, however, the slice shoule be free if (target.Usage != FPGATypes.SliceUsage.Free && CheckResources) { throw new ArgumentException("Can not place library element at " + target + " as this slice is already used"); } if (target.SliceName.Equals("SLICE_X33Y88")) { } // can be NULL in modules, should not be NULL in connection primitives if (libElement.BEL != null) { target.SetBelUsage(libElement.BEL, FPGATypes.SliceUsage.Macro); } foreach (LibraryElement libEl in libElement.SubElements.Where(l => l.BEL != null)) { target.SetBelUsage(libElement.BEL, FPGATypes.SliceUsage.Macro); } targets.Add(target); break; } } foreach (Slice t in targets) { t.Usage = FPGATypes.SliceUsage.Macro; } }