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); }
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); }
/// <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 + ")"); } } } }
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); }
/// <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); }