1 import matplotlib.cm
as cm
2 import matplotlib
as matplotlib
3 from matplotlib.colors
import Normalize
4 import matplotlib.pyplot
as plt
5 import matplotlib.patches
as patches
8 from matplotlib.patches
import Patch
14 assert(len(sys.argv) == 3)
16 targetPath = sys.argv[1]
17 deviceName = sys.argv[2]
21 def __init__(self, siteName, tileName, clockRegionName, siteType, tileType):
27 self.
L =
not (tileName.find(
"_R_") >= 0
or tileName.find(
28 "DSP") >= 0
or tileName.find(
"PCIE_X") == 0)
30 self.
X = int(tileName[tileName.rfind(
"_X")+2:tileName.rfind(
"Y")])
32 if (tileName.find(
"CLE_M_R_X84") >= 0):
35 self.
Y = int(tileName[tileName.rfind(
"Y")+1:])
37 if (tileName.find(
"DSP") >= 0):
38 if (int(siteName[siteName.rfind(
"Y")+1:]) % 2 == 1):
43 if (siteType.find(
"BUFCE_LEAF_X16") >= 0):
44 if (int(siteName[siteName.rfind(
"Y")+1:]) % 2 == 1):
45 self.
Y += 2/3 + gw/2 - gw*0.3/2
47 self.
Y += 1/3 + gw/2 - gw*0.3/2
48 if (siteType.find(
"BUFCE_ROW") >= 0):
49 self.
Y += 1/2 + gw/2 - gw*0.3/2
51 self.
siteX = int(siteName[siteName.rfind(
"_X")+2:siteName.rfind(
"Y")])
52 self.
siteY = int(siteName[siteName.rfind(
"Y")+1:])
54 if (siteType ==
"HPIOB" or siteType ==
"HRIO" or siteType ==
"BITSLICE_RX_TX"):
55 self.
Y = self.
siteY//26 * 30 + ((self.
siteY) % 26+1)/28*30
56 if (siteType ==
"BITSLICE_CONTROL" or siteType ==
"BITSLICE_TX"):
57 self.
Y = self.
siteY//4 * 30 + ((self.
siteY) % 4+0.5)/5*30
58 if (siteType ==
"RIU_OR"):
59 self.
Y = self.
siteY//2 * 30 + ((self.
siteY) % 2+0.5)/3*30
60 if (siteType ==
"PLLE3_ADV"):
70 sites_in_GTH_R = dict()
73 if (curSite.tileName.find(
"GTH_R") == 0):
74 if (
not curSite.tileName
in sites_in_GTH_R.keys()):
75 sites_in_GTH_R[curSite.tileName] = []
76 sites_in_GTH_R[curSite.tileName].append(curSite)
78 for tileName
in sites_in_GTH_R.keys():
83 for curSite
in sites_in_GTH_R[tileName]:
84 if (curSite.siteType ==
"BUFG_GT_SYNC"):
85 BUFG_GT_SYNCs.append(curSite)
86 elif (curSite.siteType ==
"GTHE3_CHANNEL"):
87 GTHE3_CHANNELs.append(curSite)
88 elif (curSite.siteType ==
"BUFG_GT"):
89 BUFG_GTs.append(curSite)
90 elif (curSite.siteType ==
"GTHE3_COMMON"):
91 GTHE3_COMMON.append(curSite)
93 BUFG_GT_SYNCs = sorted(
94 BUFG_GT_SYNCs, key=
lambda curSite: curSite.siteY)
95 GTHE3_CHANNELs = sorted(
96 GTHE3_CHANNELs, key=
lambda curSite: curSite.siteY)
97 BUFG_GTs = sorted(BUFG_GTs, key=
lambda curSite: curSite.siteY)
99 GTHE3_COMMON[0].Y = GTHE3_COMMON[0].Y + (59+gw)/2 - 1
100 BUFG_GT_SYNCs[5].Y = GTHE3_COMMON[0].Y + 1
102 GTHE3_CHANNELs[0].Y = GTHE3_COMMON[0].Y - 5
103 GTHE3_CHANNELs[1].Y = GTHE3_CHANNELs[0].Y + 2
104 GTHE3_CHANNELs[3].Y = GTHE3_COMMON[0].Y + 5
105 GTHE3_CHANNELs[2].Y = GTHE3_CHANNELs[3].Y - 2
107 for curSite
in BUFG_GT_SYNCs:
112 for curSite
in BUFG_GTs[:12]:
113 curSite.Y += initOffset
118 for curSite
in reversed(BUFG_GTs[12:]):
119 curSite.Y += initOffset
124 for curSite
in BUFG_GT_SYNCs[:5]:
125 curSite.Y += initOffset
130 for curSite
in reversed(BUFG_GT_SYNCs[6:]):
131 curSite.Y += initOffset
136 sites_in_GTY_Quad = dict()
138 for curSite
in sites:
139 if (curSite.tileName.find(
"GTY_QUAD_LEFT_FT") == 0):
140 if (
not curSite.tileName
in sites_in_GTY_Quad.keys()):
141 sites_in_GTY_Quad[curSite.tileName] = []
142 sites_in_GTY_Quad[curSite.tileName].append(curSite)
144 for tileName
in sites_in_GTY_Quad.keys():
149 for curSite
in sites_in_GTY_Quad[tileName]:
150 if (curSite.siteType ==
"BUFG_GT_SYNC"):
151 BUFG_GT_SYNCs.append(curSite)
152 elif (curSite.siteType ==
"GTYE3_CHANNEL"):
153 GTYE3_CHANNELs.append(curSite)
154 elif (curSite.siteType ==
"BUFG_GT"):
155 BUFG_GTs.append(curSite)
156 elif (curSite.siteType ==
"GTYE3_COMMON"):
157 GTYE3_COMMON.append(curSite)
159 BUFG_GT_SYNCs = sorted(
160 BUFG_GT_SYNCs, key=
lambda curSite: curSite.siteY)
161 GTYE3_CHANNELs = sorted(
162 GTYE3_CHANNELs, key=
lambda curSite: curSite.siteY)
163 BUFG_GTs = sorted(BUFG_GTs, key=
lambda curSite: curSite.siteY)
165 GTYE3_COMMON[0].Y = GTYE3_COMMON[0].Y + (59+gw)/2 - 1
166 BUFG_GT_SYNCs[5].Y = GTYE3_COMMON[0].Y + 1
168 GTYE3_CHANNELs[0].Y = GTYE3_COMMON[0].Y - 5
169 GTYE3_CHANNELs[1].Y = GTYE3_CHANNELs[0].Y + 2
170 GTYE3_CHANNELs[3].Y = GTYE3_COMMON[0].Y + 5
171 GTYE3_CHANNELs[2].Y = GTYE3_CHANNELs[3].Y - 2
173 for curSite
in BUFG_GT_SYNCs:
178 for curSite
in BUFG_GTs[:12]:
179 curSite.Y += initOffset
184 for curSite
in reversed(BUFG_GTs[12:]):
185 curSite.Y += initOffset
190 for curSite
in BUFG_GT_SYNCs[:5]:
191 curSite.Y += initOffset
196 for curSite
in reversed(BUFG_GT_SYNCs[6:]):
197 curSite.Y += initOffset
209 archive = zipfile.ZipFile(targetPath+
"/"+deviceName +
210 "/"+deviceName+
"_DeviceSite.zip",
'r')
211 lines = archive.read(deviceName+
"_DeviceSite").decode(
'utf-8').split(
"\n")
213 plotPriority = dict()
221 siteName2site = dict()
226 bel_site_tile_clockRegion_sitetype_tiletype = line.replace(
"\n",
"").replace(
"bel=> ",
"").replace(
227 " site=> ",
";").replace(
" tile=> ",
";").replace(
" sitetype=> ",
";").replace(
" clockRegion=> ",
";").replace(
" tiletype=> ",
";").split(
";")
228 if (len(bel_site_tile_clockRegion_sitetype_tiletype) < 2):
231 if (bel_site_tile_clockRegion_sitetype_tiletype[1]
in insertedSite):
232 siteName2site[bel_site_tile_clockRegion_sitetype_tiletype[1]].BELs.append(
233 bel_site_tile_clockRegion_sitetype_tiletype[0])
236 insertedSite.add(bel_site_tile_clockRegion_sitetype_tiletype[1])
237 tmpSiteInfo =
siteInfo(bel_site_tile_clockRegion_sitetype_tiletype[1], bel_site_tile_clockRegion_sitetype_tiletype[2], bel_site_tile_clockRegion_sitetype_tiletype[3],
238 bel_site_tile_clockRegion_sitetype_tiletype[4], bel_site_tile_clockRegion_sitetype_tiletype[5])
239 sites.append(tmpSiteInfo)
240 siteName2site[tmpSiteInfo.siteName] = tmpSiteInfo
241 siteName2site[bel_site_tile_clockRegion_sitetype_tiletype[1]].BELs.append(
242 bel_site_tile_clockRegion_sitetype_tiletype[0])
243 siteTypes.add(tmpSiteInfo.siteType)
244 if (
not tmpSiteInfo.siteType
in siteType2id.keys()):
245 siteType2id[tmpSiteInfo.siteType] = len(siteTypes)
248 norm = Normalize(vmin=0, vmax=len(siteTypes))
250 plotPriority = dict()
251 for name
in siteTypes:
252 plotPriority[name] = 0
253 plotPriority[
'RAMBFIFO36'] = -1
256 for curSite
in sites:
257 priorityArr.append(plotPriority[curSite.siteType])
258 priorityArr = np.array(priorityArr)
259 order = np.argsort(priorityArr)
263 for name
in siteTypes:
265 height[
'RAMBFIFO36'] = 4 + gw
266 height[
'RAMB181'] = height[
'RAMBFIFO36']/2 - gw/4
267 height[
'RAMBFIFO18'] = height[
'RAMBFIFO36']/2 - gw/4
268 height[
'DSP48E2_T'] = height[
'RAMBFIFO36']/2 - gw/4
269 height[
'DSP48E2_B'] = height[
'RAMBFIFO36']/2 - gw/4
271 height[
'BUFCE_LEAF_X16'] = gw*0.3
272 height[
'BUFCE_ROW'] = gw*0.3
275 for name
in siteTypes:
277 weight[
'RAMBFIFO36'] = gw*1.3
278 weight[
'BUFG_GT'] = gw*0.3
279 weight[
'BUFG_GT_SYNC'] = gw*0.3
280 weight[
'BUFCE_LEAF_X16'] = gw*0.3
281 weight[
'BUFCE_ROW'] = gw*0.3
284 for name
in siteTypes:
286 yoffset[
'RAMB181'] = 2 + gw/2 + gw/4/2
287 yoffset[
'RAMBFIFO18'] = gw/4/2
288 yoffset[
'DSP48E2_T'] = 2 + gw/2 + gw/4/2
289 yoffset[
'DSP48E2_B'] = gw/4/2
293 for curSite
in sites:
294 if (curSite.X >= 34):
296 if (curSite.X >= 53):
298 if (curSite.tileName.find(
"HRIO_L_X") == 0):
300 if (curSite.tileName.find(
"HPIO_L_X") == 0):
306 fig, ax = plt.subplots(1)
308 ax.set_ylim([0, 500])
310 arr = np.arange(len(siteTypes)+1)
312 np.random.shuffle(arr)
317 sites = np.array(sites)
320 addedPatchTypes = set()
321 for curSite
in sites:
323 rect = patches.Rectangle(((curSite.X-0.25-weight[curSite.siteType]/2), curSite.Y-gw/2 + yoffset[curSite.siteType]),
324 weight[curSite.siteType], height[curSite.siteType], color=
cmap(
norm(arr[siteType2id[curSite.siteType]])))
326 curSite.X-0.25-weight[curSite.siteType]/2) + weight[curSite.siteType]/2
327 curSite.centerY = curSite.Y-gw/2 + \
328 yoffset[curSite.siteType] + height[curSite.siteType]/2
330 rect = patches.Rectangle(((curSite.X+0.25-weight[curSite.siteType]/2), curSite.Y-gw/2 + yoffset[curSite.siteType]),
331 weight[curSite.siteType], height[curSite.siteType], color=
cmap(
norm(arr[siteType2id[curSite.siteType]])))
333 curSite.X+0.25-weight[curSite.siteType]/2) + weight[curSite.siteType]/2
334 curSite.centerY = curSite.Y-gw/2 + \
335 yoffset[curSite.siteType] + height[curSite.siteType]/2
337 if (
not curSite.siteType
in addedPatchTypes):
338 addedPatchTypes.add(curSite.siteType)
339 legend_elements.append(Patch(color=
cmap(
340 norm(arr[siteType2id[curSite.siteType]])), label=curSite.siteType))
350 exportfile = open(targetPath+
"/"+deviceName+
"/" +
351 deviceName+
"_exportSiteLocation",
"w")
353 for curSite
in sites:
356 if (curSite.siteType.find(
"DSP") >= 0):
357 curSite.siteType = curSite.siteType[:-2]
358 if (curSite.siteName.find(
"DSP") >= 0
or curSite.siteName.find(
"RAMB") >= 0):
359 if (curSite.siteY % 2 == 1):
360 cy = curSite.centerY + (1-gw)/2
362 print(
"site=> " + curSite.siteName
363 +
" tile=> " + curSite.tileName
364 +
" clockRegionName=> " + curSite.clockRegionName
365 +
" sitetype=> " + curSite.siteType
366 +
" tiletype=> " + curSite.tileType
367 +
" centerx=> " + str(cx)
368 +
" centery=> " + str(cy)
369 +
" BELs=> " + str(curSite.BELs).replace(
" ",
"").replace(
"\'",
""), file=exportfile)
372 os.system(
"zip -j "+targetPath+
"/"+deviceName+
"/" +
373 deviceName+
"_exportSiteLocation.zip "+targetPath+
"/"+deviceName+
"/" +
374 deviceName+
"_exportSiteLocation")