11/*
2- * Copyright (c) 2022, Advanced Micro Devices, Inc.
2+ * Copyright (c) 2022-2025 , Advanced Micro Devices, Inc.
33 * All rights reserved.
44 *
55 * Author: Chris Lavin, AMD AECG Research Labs.
2222
2323package com .xilinx .rapidwright .device ;
2424
25+ import java .util .EnumSet ;
2526import java .util .HashMap ;
2627import java .util .Map ;
2728
29+ import com .xilinx .rapidwright .util .Utils ;
30+
2831public class DeviceTools {
2932
3033 /**
3134 * Maps from the Name Root to a name that is equal for all relocatable tiles
3235 */
3336 private static Map <String , String > versalHalfFSRTileTypes ;
3437
38+ /**
39+ * Map for each series site type to have an input to trace back to a
40+ * corresponding INT tile
41+ */
42+ private static HashMap <Series , HashMap <SiteTypeEnum , String >> traceIntPinNames ;
43+
44+ private static EnumSet <SiteTypeEnum > versalIRIQuadTypes ;
45+
3546 static {
3647
3748 versalHalfFSRTileTypes = new HashMap <>();
@@ -58,6 +69,99 @@ public class DeviceTools {
5869
5970 // URAMs on 7 series
6071 versalHalfFSRTileTypes .put ("URAM_URAM_DELAY_FT" , "URAM_URAM_FT" );
72+
73+ traceIntPinNames = new HashMap <>();
74+ HashMap <SiteTypeEnum , String > series7 = new HashMap <>();
75+ HashMap <SiteTypeEnum , String > ultrascale = new HashMap <>();
76+ HashMap <SiteTypeEnum , String > ultrascalePlus = new HashMap <>();
77+ HashMap <SiteTypeEnum , String > versal = new HashMap <>();
78+ traceIntPinNames .put (Series .Series7 , series7 );
79+ traceIntPinNames .put (Series .UltraScale , ultrascale );
80+ traceIntPinNames .put (Series .UltraScalePlus , ultrascalePlus );
81+ traceIntPinNames .put (Series .Versal , versal );
82+
83+ // SLICEL / SLICEM
84+ series7 .put (SiteTypeEnum .SLICEL , "CLK" );
85+ series7 .put (SiteTypeEnum .SLICEM , "CLK" );
86+ ultrascale .put (SiteTypeEnum .SLICEL , "CLK_B1" );
87+ ultrascale .put (SiteTypeEnum .SLICEM , "CLK_B1" );
88+ ultrascalePlus .put (SiteTypeEnum .SLICEL , "CLK1" );
89+ ultrascalePlus .put (SiteTypeEnum .SLICEM , "CLK1" );
90+ versal .put (SiteTypeEnum .SLICEL , "AX" ); // CLK/RST sometimes trace to CLE_BC (local INT btw b2b
91+ // slices)
92+ versal .put (SiteTypeEnum .SLICEM , "AX" );
93+
94+ // DSP
95+ series7 .put (SiteTypeEnum .DSP48E1 , "CLK" );
96+ ultrascale .put (SiteTypeEnum .DSP48E2 , "CLK_B" );
97+ ultrascalePlus .put (SiteTypeEnum .DSP48E2 , "CLK" );
98+
99+ // BRAM
100+ series7 .put (SiteTypeEnum .RAMBFIFO36E1 , "CLKARDCLKL" );
101+ ultrascale .put (SiteTypeEnum .RAMBFIFO36 , "CLKAL_X" );
102+ ultrascalePlus .put (SiteTypeEnum .RAMBFIFO36 , "CLKAL" );
103+
104+ series7 .put (SiteTypeEnum .RAMB36E1 , "CLKARDCLKL" );
105+ ultrascale .put (SiteTypeEnum .RAMB36 , "CLKAL_X" );
106+ ultrascalePlus .put (SiteTypeEnum .RAMB36 , "CLKAL" );
107+ versal .put (SiteTypeEnum .RAMB36 , "ADDRARDADDRL_0_" );
108+
109+ series7 .put (SiteTypeEnum .FIFO36E1 , "RDCLKL" );
110+ ultrascale .put (SiteTypeEnum .FIFO36 , "CLKAL_X" );
111+ ultrascalePlus .put (SiteTypeEnum .FIFO36 , "CLKAL" );
112+
113+ ultrascale .put (SiteTypeEnum .RAMBFIFO18 , "CLKAL_X" );
114+ ultrascalePlus .put (SiteTypeEnum .RAMBFIFO18 , "CLKAL" );
115+
116+ series7 .put (SiteTypeEnum .RAMB18E1 , "CLKARDCLK" );
117+ ultrascale .put (SiteTypeEnum .RAMB180 , "CLKAL_X" );
118+ ultrascalePlus .put (SiteTypeEnum .RAMB180 , "CLKAL" );
119+ versal .put (SiteTypeEnum .RAMB18_U , "ADDRARDADDR_0_" );
120+
121+ series7 .put (SiteTypeEnum .FIFO18E1 , "RDCLK" );
122+ ultrascale .put (SiteTypeEnum .FIFO18_0 , "CLKAL_X" );
123+ ultrascalePlus .put (SiteTypeEnum .FIFO18_0 , "CLKAL" );
124+
125+ ultrascale .put (SiteTypeEnum .RAMB181 , "CLKAU_X" );
126+ ultrascalePlus .put (SiteTypeEnum .RAMB181 , "CLKAU" );
127+ versal .put (SiteTypeEnum .RAMB18_L , "ADDRARDADDR_0_" );
128+
129+ ultrascalePlus .put (SiteTypeEnum .URAM288 , "CLK" );
130+
131+ ultrascale .put (SiteTypeEnum .LAGUNA , "TX_CLK" );
132+ ultrascalePlus .put (SiteTypeEnum .LAGUNA , "TX_CLK" );
133+
134+ for (SiteTypeEnum t : new SiteTypeEnum [] { SiteTypeEnum .OLOGICE2 , SiteTypeEnum .OLOGICE3 ,
135+ SiteTypeEnum .OSERDESE2 }) {
136+ series7 .put (t , "D1" );
137+ }
138+ for (SiteTypeEnum t : new SiteTypeEnum [] { SiteTypeEnum .PHASER_OUT_PHY ,
139+ SiteTypeEnum .PHASER_OUT , SiteTypeEnum .PHASER_OUT_ADV ,
140+ SiteTypeEnum .PHASER_IN_PHY , SiteTypeEnum .PHASER_IN ,
141+ SiteTypeEnum .PHASER_IN_ADV }) {
142+ series7 .put (t , "SYSCLK" );
143+ }
144+ for (SiteTypeEnum t : new SiteTypeEnum [] { SiteTypeEnum .IOB33 , SiteTypeEnum .IOB33M ,
145+ SiteTypeEnum .IOB33S }) {
146+ series7 .put (t , "INTERMDISABLE" );
147+ }
148+ series7 .put (SiteTypeEnum .GTHE2_COMMON , "DRPCLK" );
149+ series7 .put (SiteTypeEnum .PHY_CONTROL , "PHYCLK" );
150+
151+ ultrascalePlus .put (SiteTypeEnum .HPIOB_M , "IBUF_DISABLE" );
152+ ultrascalePlus .put (SiteTypeEnum .HPIOB_S , "IBUF_DISABLE" );
153+ ultrascalePlus .put (SiteTypeEnum .BITSLICE_RX_TX , "TX_D0" );
154+
155+ ultrascalePlus .put (SiteTypeEnum .BUFG_GT , "CEMASK" );
156+
157+ versal .put (SiteTypeEnum .DSP58_PRIMARY , "A_0_" );
158+ versal .put (SiteTypeEnum .DSP58_CPLX , "A_CPLX_L_0_" );
159+ versal .put (SiteTypeEnum .IRI_QUAD_EVEN , "IMUX_IN0" );
160+ versal .put (SiteTypeEnum .IRI_QUAD_ODD , "IMUX_IN0" );
161+ versal .put (SiteTypeEnum .URAM288 , "ADDR_A_0_" );
162+ versalIRIQuadTypes = EnumSet .of (SiteTypeEnum .DSP58_PRIMARY , SiteTypeEnum .DSP58_CPLX ,
163+ SiteTypeEnum .URAM288 , SiteTypeEnum .RAMB36 , SiteTypeEnum .RAMB18_L ,
164+ SiteTypeEnum .RAMB18_U );
61165 }
62166
63167 public static Map <String , Tile [][]> createTileByRootNameCache (Device device ) {
@@ -97,4 +201,80 @@ public static Map<String, Tile[][]> createTileByRootNameCache(Device device) {
97201
98202 return tileByRootNameCache ;
99203 }
204+
205+ private static String pinNameToFollow (Series s , SiteTypeEnum type ) {
206+ return traceIntPinNames .get (s ).get (type );
207+ }
208+
209+ /**
210+ * Gets the approximate INT tile to which this site connects. Some site types
211+ * connect to more than one INT tile, thus the returned INT tile could be
212+ * arbitrary. Note: This method was moved from {@link Site#getIntTile()} in
213+ * 2025.1.2.
214+ *
215+ * @return The approximate INT tile connected to this site or null if none could
216+ * be found.
217+ */
218+ public static Tile getIntTile (Site site ) {
219+ SiteTypeEnum type = site .getSiteTypeEnum ();
220+ Series series = site .getDevice ().getSeries ();
221+ String pinName = pinNameToFollow (series , type );
222+ if (pinName == null && site .getSitePinCount () > 0 ) {
223+ // Let's try for a different pin
224+ pinName = site .getPinName (0 );
225+ }
226+ int wire = site .getTileWireIndexFromPinName (pinName );
227+ if (wire < 0 ) {
228+ return null ;
229+ }
230+ Tile tile = site .getTile ();
231+ Node n = Node .getNode (tile , wire );
232+ if (series == Series .Versal ) {
233+ n = n .getAllUphillNodes ().get (0 );
234+ if (versalIRIQuadTypes .contains (type )) {
235+ // These sites must pass through an IRI_QUAD type first before getting to the
236+ // INT tile
237+ SitePin iriQuad = n .getAllUphillNodes ().get (0 ).getSitePin ();
238+ return getIntTile (iriQuad .getSite ());
239+ } else if (type == SiteTypeEnum .DSP58_CPLX ) {
240+ // This must pass through the DSP58_PRIMARY type before getting to the IRI_QUAD
241+ SitePin dsp58Primary = n .getAllUphillNodes ().get (0 ).getSitePin ();
242+ return getIntTile (dsp58Primary .getSite ());
243+ }
244+ }
245+ for (Wire w : n .getAllWiresInNode ()) {
246+ if (Utils .isSwitchBox (w .getTile ().getTileTypeEnum ())) {
247+ return w .getTile ();
248+ }
249+ }
250+ for (PIP p : n .getTile ().getBackwardPIPs (n .getWireIndex ())) {
251+ Wire w = p .getStartWire ();
252+ for (Wire w2 : w .getNode ().getAllWiresInNode ()) {
253+ if (Utils .isSwitchBox (w2 .getTile ().getTileTypeEnum ())) {
254+ return w2 .getTile ();
255+ }
256+ }
257+ if (site .getName ().startsWith ("IOB_" )) {
258+ for (PIP p2 : w .getStartWire ().getBackwardPIPs ()) {
259+ Wire w3 = p2 .getStartWire ();
260+ for (Wire w4 : w3 .getNode ().getAllWiresInNode ()) {
261+ if (Utils .isSwitchBox (w4 .getTile ().getTileTypeEnum ())) {
262+ return w4 .getTile ();
263+ }
264+ }
265+ }
266+ }
267+ }
268+
269+ for (PIP p : n .getTile ().getPIPs (n .getWireIndex ())) {
270+ Wire w = p .getEndWire ();
271+ for (Wire w2 : w .getNode ().getAllWiresInNode ()) {
272+ if (Utils .isSwitchBox (w2 .getTile ().getTileTypeEnum ())) {
273+ return w2 .getTile ();
274+ }
275+ }
276+ }
277+
278+ return null ;
279+ }
100280}
0 commit comments