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);
            }
        }
Beispiel #3
0
        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;
            }
        }