AMF-Placer  2.0
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
VivadoGraphUtil.py
Go to the documentation of this file.
1 import networkx as nx
2 
3 
4 class VivadoCell(object):
5  def __init__(self, id, name, refType, pins, netStr, drivepinStr):
6  self.id = id
7  self.name = name
8  self.refType = refType
9  self.pins = pins
10  self.netStr = netStr
11  self.drivepinStr = drivepinStr
12  self.drivepins_fromOthers = set()
13 
14  def bindPinDriveObjs(self, pinName2Obj):
15  self.drivepins = []
16  assert(len(self.drivepinStr) == len(self.pins))
17  for i in range(len(self.drivepinStr)):
18  tmpName = self.drivepinStr[i]
19  pin = self.pins[i]
20  if ((tmpName in pinName2Obj.keys()) and (not pin is None)):
21  self.drivepins.append(pinName2Obj[tmpName])
22  else:
23  if (tmpName.find("VCC") < 0 and tmpName.find("GND") < 0 and len(tmpName) > 0):
24  if (tmpName.find("en_sig_1/G") < 0):
25  print("pin might have problem: ", tmpName)
26  self.drivepins.append(None)
27  continue
28  if (pin.dir):
29  self.drivepins_fromOthers.add(self.drivepins[-1])
30 
31 
32 class VivadoPin(object):
33  def __init__(self, name, refName, nameOnCell, dir, cell):
34  self.name = name
35  self.dir = dir
36  self.cell = cell
37  self.refName = refName
38  self.nameOnCell = nameOnCell
39 
40 
41 class VivadoNet(object):
42  def __init__(self, name, inputpins, outputpins):
43  self.name = name
44  self.inputpins = inputpins
45  self.outputpins = outputpins
46 
47 
48 class VivadoCoreCluster(object):
49  def __init__(self, coreType, coreNodes, patternStr, nodeInCluster):
50  self.coreType = coreType
51  self.coreNodes = coreNodes
52  self.patternStr = patternStr
53  self.nodeInCluster = nodeInCluster
54 
55 
56 class VivadoPatternCluster(object):
57  def __init__(self, initPatternStr, unextendedNodes, extendedNodes, clusterId):
58  self.patternExtensionTrace = initPatternStr.replace(
59  "\'", "").replace("\\", "")
60  self.unextendedNodes = unextendedNodes
61  self.extendedNodes = extendedNodes
62  self.disabled = False
63  self.clusterId = clusterId
64 
65 
67  def __init__(self, initPatternStr, patternClusters):
68  self.patternExtensionTrace = initPatternStr.replace(
69  "\'", "").replace("\\", "")
70  self.patternClusters = patternClusters
71 
72 
73 def loadCellInfoFromFile(textFile):
74 
75  firstCell = True
76 
77  VivadoCells = []
78  cellName2Obj = dict()
79  pinName2Obj = dict()
80  idCnt = 0
81  for line in textFile.decode('utf-8').split("\n"):
82 
83  # print(line)
84 
85  if (line.find("curCell=> ") >= 0):
86 
87  if (not firstCell):
88  if (not (curCell is None)):
89  if (not curCell.name in cellName2Obj.keys()):
90  VivadoCells.append(curCell)
91  cellName2Obj[curCell.name] = curCell
92  else:
93  print("WARNING duplicate cell:", curCell.name)
94  firstCell = False
95 
96  name_type = line.replace("curCell=> ", "").split(" type=> ")
97  name = name_type[0]
98  refType = name_type[1]
99  if (name in cellName2Obj.keys()):
100  curCell = None
101  else:
102  curCell = VivadoCell(idCnt, name, refType, [], [], [])
103  idCnt += 1
104 
105  continue
106 
107  if (line.find(" pin=> ") >= 0):
108  if (curCell is None):
109  continue
110  pin_refpin_dir_net_drivepin = line.replace(" pin=> ", "").replace(" refpin=> ", ";").replace(
111  " dir=> ", ";").replace(" net=> ", ";").replace(" drivepin=> ", ";").split(";")
112 
113  if (len(pin_refpin_dir_net_drivepin) > 5):
114  assert(False) # we don't expect multi-driver
115 
116  if (pin_refpin_dir_net_drivepin[4].replace("\n", "") != ""):
117  curCell.netStr.append(
118  pin_refpin_dir_net_drivepin[3].replace("\n", ""))
119  curCell.drivepinStr.append(
120  pin_refpin_dir_net_drivepin[4].replace("\n", ""))
121 
122  if (pin_refpin_dir_net_drivepin[2] == "OUT"):
123  if (pin_refpin_dir_net_drivepin[0] != pin_refpin_dir_net_drivepin[4].replace("\n", "")):
124  curPin = VivadoPin(pin_refpin_dir_net_drivepin[4].replace(
125  "\n", ""), pin_refpin_dir_net_drivepin[1], pin_refpin_dir_net_drivepin[0], pin_refpin_dir_net_drivepin[2] == "IN", curCell)
126  else:
127  curPin = VivadoPin(pin_refpin_dir_net_drivepin[0], pin_refpin_dir_net_drivepin[1],
128  pin_refpin_dir_net_drivepin[0], pin_refpin_dir_net_drivepin[2] == "IN", curCell)
129  else:
130  curPin = VivadoPin(pin_refpin_dir_net_drivepin[0], pin_refpin_dir_net_drivepin[1],
131  pin_refpin_dir_net_drivepin[0], pin_refpin_dir_net_drivepin[2] == "IN", curCell)
132 
133  if (curPin.name == ""):
134  continue
135 
136  if (not curPin.name in pinName2Obj.keys()):
137  pinName2Obj[curPin.name] = curPin
138  curCell.pins.append(curPin)
139 
140  VivadoCells.append(curCell)
141  cellName2Obj[curCell.name] = curCell
142 
143  for curCell in VivadoCells:
144  curCell.bindPinDriveObjs(pinName2Obj)
145 
146  return VivadoCells
147 
148 
150  inputPatterns = dict()
151  inputPatterns_Cells = dict()
152  cellTypes = dict()
153  outputPatternCnt = dict()
154 
155  netlist = []
156  netset = set()
157  netstr2Tuple = dict()
158  netstr2netnum = dict()
159  cellname2id = dict()
160  nodetype = dict()
161  nodename = dict()
162  node2id = dict()
163  for tmpCell in VivadoCells:
164  outputPatternCnt[tmpCell.id] = dict()
165 
166  VivadoGraph = nx.DiGraph()
167  edgeAttributes = []
168  for tmpCell in VivadoCells:
169 
170  nodetype[tmpCell.id] = tmpCell.refType
171  nodename[tmpCell.id] = tmpCell.name
172  node2id[tmpCell.id] = tmpCell.id
173  cellname2id[tmpCell.name] = tmpCell.id
174  VivadoGraph.add_node(tmpCell.id)
175 
176  if (not(tmpCell.refType in cellTypes.keys())):
177  cellTypes[tmpCell.refType] = 0
178  cellTypes[tmpCell.refType] += 1
179 
180  driverTypeCnt = dict()
181  driverCheck = set()
182 
183  for pin, net, drivepin in zip(tmpCell.pins, tmpCell.netStr, tmpCell.drivepins):
184 
185  if (not (drivepin is None)):
186  if (pin.dir and net != ""):
187  # if (tmpCell.name == "design_1_i/face_detect_0/inst/grp_processImage_fu_371/SI_V_10_49_1_reg_26649_reg"):
188  # print("pin=>", pin.name, "drivepin.cell=>", drivepin.cell.name, "drivepin=>", drivepin.name)
189  tmp_netTuple = (drivepin.cell.id, tmpCell.id)
190  edgeAttributes.append(
191  (drivepin.cell.id, tmpCell.id, drivepin.cell.refType+"-"+drivepin.refName))
192  tmp_netTuple_Str = tmp_netTuple
193  if (not(tmp_netTuple_Str in netset)):
194  netset.add(tmp_netTuple_Str)
195  netstr2Tuple[tmp_netTuple_Str] = tmp_netTuple
196  netstr2netnum[tmp_netTuple_Str] = 0
197  netstr2netnum[tmp_netTuple_Str] += 1
198 
199  for key in netstr2netnum.keys():
200  netlist.append(
201  (netstr2Tuple[key][0], netstr2Tuple[key][1], netstr2netnum[key]))
202 
203  VivadoGraph.add_weighted_edges_from(netlist)
204 
205  for a, b, driverPinType in edgeAttributes:
206  VivadoGraph[a][b]['driverPinType'] = driverPinType
207 
208  nx.set_node_attributes(VivadoGraph, name="name", values=nodename)
209  nx.set_node_attributes(VivadoGraph, name="type", values=nodetype)
210  nx.set_node_attributes(VivadoGraph, name="id", values=node2id)
211  print("#nodes:", VivadoGraph.number_of_nodes())
212  print("#edges:", VivadoGraph.number_of_edges())
213 
214  return VivadoGraph
215 
216 
217 def getInitalSingleCorePatterns(VivadoGraph, careTypeList, coreType="CARRY", checkDirection="both", allowOverlap=True, onlyRecordInput=False):
218 
219  careTypeList = set(careTypeList)
220 
221  singleCorePattern = None
222 
223  if (checkDirection == "both"):
224  inCheck = True
225  outCheck = True
226  elif (checkDirection == "in"):
227  inCheck = True
228  outCheck = False
229  elif (checkDirection == "out"):
230  inCheck = False
231  outCheck = True
232  else:
233  assert(False)
234 
235  singleCorePattern = dict()
236 
237  traversedNodes = set()
238 
239  for nodeId in VivadoGraph.nodes():
240  curNode = VivadoGraph.nodes()[nodeId]
241 
242  nodeType = curNode['type']
243  if (nodeType.find(coreType) >= 0):
244 
245  if ((nodeId in traversedNodes) and (not allowOverlap)):
246  continue
247 
248  nodeInPattern = set()
249  nodeInPattern.add(nodeId)
250  traversedNodes.add(nodeId)
251  predTypeCnt = dict()
252  if (inCheck):
253  for pred in VivadoGraph.predecessors(nodeId):
254  if ((pred in traversedNodes) and (not allowOverlap)):
255  continue
256  nodeInPattern.add(pred)
257  traversedNodes.add(pred)
258  predNode = VivadoGraph.nodes()[pred]
259  if (not predNode['type'] in careTypeList):
260  continue
261  if (not (predNode['type'] in predTypeCnt.keys())):
262  predTypeCnt[predNode['type']] = 0
263  predTypeCnt[predNode['type']
264  ] += VivadoGraph[pred][nodeId]['weight']
265 
266  predTypeList = []
267  for key in predTypeCnt.keys():
268  predTypeList.append(key+"-"+str(predTypeCnt[key]))
269  predTypeList.sort()
270  predPatternStr = '-'.join(predTypeList) + ">="
271 
272  succTypeCnt = dict()
273  if (outCheck):
274  for succ in VivadoGraph.successors(nodeId):
275  if ((succ in traversedNodes) and (not allowOverlap)):
276  continue
277  if (not onlyRecordInput):
278  nodeInPattern.add(succ)
279  traversedNodes.add(succ)
280  succNode = VivadoGraph.nodes()[succ]
281  if (not succNode['type'] in careTypeList):
282  continue
283  if (not (succNode['type'] in succTypeCnt.keys())):
284  succTypeCnt[succNode['type']] = 0
285  succTypeCnt[succNode['type']
286  ] += VivadoGraph[nodeId][succ]['weight']
287 
288  succTypeList = []
289  for key in succTypeCnt.keys():
290  succTypeList.append(key+"-"+str(succTypeCnt[key]))
291  succTypeList.sort()
292  succPatternStr = ">=" + '-'.join(succTypeList)
293 
294  overallPatternStr = predPatternStr + nodeType + succPatternStr
295 
296  if (coreType == "MUXF7" and overallPatternStr.find("MUXF8") >= 0):
297  continue
298 
299  if (not (overallPatternStr in singleCorePattern.keys())):
300  singleCorePattern[overallPatternStr] = []
301 
302  singleCorePattern[overallPatternStr].append(
303  (curNode, nodeInPattern))
304 
305  numSingleCorePattern = dict()
306  for key in singleCorePattern.keys():
307  numSingleCorePattern[key] = len(singleCorePattern[key])
308 
309  sortedSingleCorePattern = []
310  for w in sorted(numSingleCorePattern, key=numSingleCorePattern.get, reverse=True):
311  # if (len(singleCorePattern[w]) >= 5):
312  # print(w, len(singleCorePattern[w]))
313  sortedSingleCorePattern.append((w, singleCorePattern[w]))
314 
315  return singleCorePattern, sortedSingleCorePattern
316 
317 
318 def chainBFS(VivadoGraph, nodeId):
319 
320  coreType = VivadoGraph.nodes()[nodeId]['type']
321  curId = nodeId
322  reachSet = set()
323  curSet = set({curId})
324 
325  while (len(curSet) > 0):
326  reachSet = reachSet | curSet
327  nextSet = set()
328  for curId in curSet:
329  for succ in VivadoGraph.successors(curId):
330  if (coreType == VivadoGraph.nodes()[succ]['type']):
331  if (not (succ in reachSet)):
332  nextSet.add(succ)
333  for pred in VivadoGraph.predecessors(curId):
334  if (coreType == VivadoGraph.nodes()[pred]['type']):
335  if (not (pred in reachSet)):
336  nextSet.add(pred)
337  curSet = nextSet
338 
339  return reachSet
340 
341 
342 def clusterNodeChain(VivadoGraph, coreType="CARRY8"):
343 
344  chainedSet = set()
345  chains = []
346  for nodeId in VivadoGraph.nodes():
347  curNode = VivadoGraph.nodes()[nodeId]
348  nodeType = curNode['type']
349  if (nodeType.find(coreType) >= 0):
350  if (nodeId in chainedSet):
351  continue
352  coreNodes = chainBFS(VivadoGraph, nodeId)
353  chainedSet = chainedSet | coreNodes
354  chains.append(VivadoCoreCluster(nodeType, coreNodes, None, None))
355 
356  return chains
357 
358 
359 def clusterNodeWithCommonFanin(VivadoGraph, VivadoCells, targetType="RAM32M16"):
360 
361  clusteredSet = set()
362 
363  allNodesInType = []
364  for nodeId in VivadoGraph.nodes():
365  curNode = VivadoGraph.nodes()[nodeId]
366  nodeType = curNode['type']
367  if (nodeType.find(targetType) >= 0):
368  allNodesInType.append(nodeId)
369 
370  graphForCluster = nx.Graph()
371  for nodeId in allNodesInType:
372  graphForCluster.add_node(nodeId)
373 
374  edges = []
375  for listId, nodeId in enumerate(allNodesInType):
376  for other_nodeId in allNodesInType[listId+1:]:
377  driverPins = (VivadoCells[nodeId].drivepins_fromOthers) & (
378  VivadoCells[other_nodeId].drivepins_fromOthers)
379  edges.append((nodeId, other_nodeId, len(driverPins)))
380 
381  edges.sort(key=lambda tup: tup[2], reverse=True)
382 
383  node2NumCommonFanin = dict()
384 
385  for edge in edges:
386  nodeA = edge[0]
387  nodeB = edge[1]
388  numCommonFanin = edge[2]
389  if (not nodeA in node2NumCommonFanin.keys()):
390  node2NumCommonFanin[nodeA] = numCommonFanin
391  if (not nodeB in node2NumCommonFanin.keys()):
392  node2NumCommonFanin[nodeB] = numCommonFanin
393 
394  if (node2NumCommonFanin[nodeA] == node2NumCommonFanin[nodeB]):
395  graphForCluster.add_edge(nodeA, nodeB)
396 
397  clusterSet_list = []
398 
399  for edge in edges:
400  nodeA = edge[0]
401  nodeB = edge[1]
402 
403  if (not nodeA in clusteredSet):
404  overlapDriverPin = None
405  newCluster = set()
406  clusteredSet.add(nodeA)
407  newCluster.add(nodeA)
408  for nodeId in graphForCluster.neighbors(nodeA):
409  if (not nodeId in clusteredSet):
410  driverPins = (VivadoCells[nodeId].drivepins_fromOthers) & (
411  VivadoCells[nodeA].drivepins_fromOthers)
412  if (overlapDriverPin is None):
413  overlapDriverPin = driverPins
414 
415  if (overlapDriverPin == driverPins):
416  clusteredSet.add(nodeId)
417  newCluster.add(nodeId)
418 
419  clusterSet_list.append(newCluster)
420  continue
421 
422  if (not nodeB in clusteredSet):
423  overlapDriverPin = None
424  newCluster = set()
425  clusteredSet.add(nodeB)
426  newCluster.add(nodeB)
427  for nodeId in graphForCluster.neighbors(nodeB):
428  if (not nodeId in clusteredSet):
429  driverPins = (VivadoCells[nodeId].drivepins_fromOthers) & (
430  VivadoCells[nodeB].drivepins_fromOthers)
431  if (overlapDriverPin is None):
432  overlapDriverPin = driverPins
433 
434  if (overlapDriverPin == driverPins):
435  clusteredSet.add(nodeId)
436  newCluster.add(nodeId)
437 
438  clusterSet_list.append(newCluster)
439  continue
440 
441  clusters = []
442  # print("comps:")
443  for comp in clusterSet_list: # nx.connected_components(graphForCluster#
444  clusters.append(VivadoCoreCluster(targetType, comp, None, None))
445  # for id in comp:
446  # print(node2NumCommonFanin[id], VivadoGraph.nodes()[id]['name'])
447  # print("================================")
448 
449  # exit()
450  return clusters
451 
452 
453 def clusterExtendPatterns(VivadoGraph, chains, largeCluserIntoPattern=False, allowOverlap=False, largeCluserThredhold=2):
454 
455  patternStr2Chains = dict()
456  traversedNodes = set()
457 
458  largeCnt = 0
459  for chain in chains:
460  corePatternStr = chain.coreType + "-" + str(len(chain.coreNodes))
461 
462  if (largeCluserIntoPattern and len(chain.coreNodes) > largeCluserThredhold):
463  corePatternStr += "largeParallel("+str(largeCnt)+")"
464  largeCnt += 1
465  for nodeId in chain.coreNodes:
466 
467  if ((nodeId in traversedNodes) and (not allowOverlap)):
468  continue
469  traversedNodes.add(nodeId)
470 
471  nodeInPattern = set([nodeId])
472 
473  newCluster = VivadoCoreCluster(
474  chain.coreType, set(), None, None)
475  # predTypeCnt = dict()
476  # for pred in VivadoGraph.predecessors(nodeId):
477  # if ((pred in traversedNodes) and (not allowOverlap)):
478  # continue
479  # traversedNodes.add(pred)
480  # nodeInPattern.add(pred)
481  # predNode = VivadoGraph.nodes()[pred]
482  # if (not (predNode['type'] in predTypeCnt.keys())):
483  # predTypeCnt[predNode['type']] = 0
484  # predTypeCnt[predNode['type']] += VivadoGraph[pred][nodeId]['weight']
485 
486  # predTypeList = []
487  # for key in predTypeCnt.keys():
488  # predTypeList.append(key+"-"+str(predTypeCnt[key]))
489  # predTypeList.sort()
490  # predPatternStr = '-'.join(predTypeList) + ">="
491 
492  # succTypeCnt = dict()
493  # for succ in VivadoGraph.successors(nodeId):
494  # if ((succ in traversedNodes) and (not allowOverlap)):
495  # continue
496  # traversedNodes.add(succ)
497  # nodeInPattern.add(succ)
498  # succNode = VivadoGraph.nodes()[succ]
499  # if (not (succNode['type'] in succTypeCnt.keys())):
500  # succTypeCnt[succNode['type']] = 0
501  # succTypeCnt[succNode['type']] += VivadoGraph[nodeId][succ]['weight']
502 
503  # succTypeList = []
504  # for key in succTypeCnt.keys():
505  # succTypeList.append(key+"-"+str(succTypeCnt[key]))
506  # succTypeList.sort()
507  # succPatternStr = ">=" + '-'.join(succTypeList)
508 
509  # overallPatternStr = predPatternStr + corePatternStr + succPatternStr
510  overallPatternStr = ">=" + corePatternStr + ">="
511  newCluster.patternStr = overallPatternStr
512  newCluster.nodeInCluster = nodeInPattern
513 
514  if (not (overallPatternStr in patternStr2Chains.keys())):
515  patternStr2Chains[overallPatternStr] = []
516 
517  patternStr2Chains[overallPatternStr].append(newCluster)
518 
519  else:
520  nodeInPattern = chain.coreNodes.copy() - traversedNodes
521 
522  predTypeCnt = dict()
523  for nodeId in chain.coreNodes - traversedNodes:
524  for pred in VivadoGraph.predecessors(nodeId):
525  if ((pred in traversedNodes) and (not allowOverlap)):
526  continue
527  traversedNodes.add(pred)
528  nodeInPattern.add(pred)
529  predNode = VivadoGraph.nodes()[pred]
530  if (not (predNode['type'] in predTypeCnt.keys())):
531  predTypeCnt[predNode['type']] = 0
532  predTypeCnt[predNode['type']
533  ] += VivadoGraph[pred][nodeId]['weight']
534 
535  predTypeList = []
536  for key in predTypeCnt.keys():
537  predTypeList.append(key+"-"+str(predTypeCnt[key]))
538  predTypeList.sort()
539  predPatternStr = '-'.join(predTypeList) + ">="
540 
541  succTypeCnt = dict()
542  for nodeId in chain.coreNodes - traversedNodes:
543  for succ in VivadoGraph.successors(nodeId):
544  if ((succ in traversedNodes) and (not allowOverlap)):
545  continue
546  traversedNodes.add(succ)
547  nodeInPattern.add(succ)
548  succNode = VivadoGraph.nodes()[succ]
549  if (not (succNode['type'] in succTypeCnt.keys())):
550  succTypeCnt[succNode['type']] = 0
551  succTypeCnt[succNode['type']
552  ] += VivadoGraph[nodeId][succ]['weight']
553 
554  succTypeList = []
555  for key in succTypeCnt.keys():
556  succTypeList.append(key+"-"+str(succTypeCnt[key]))
557  succTypeList.sort()
558  succPatternStr = ">=" + '-'.join(succTypeList)
559 
560  overallPatternStr = predPatternStr + corePatternStr + succPatternStr
561 
562  chain.patternStr = overallPatternStr
563  chain.nodeInCluster = nodeInPattern
564 
565  if (not (overallPatternStr in patternStr2Chains.keys())):
566  patternStr2Chains[overallPatternStr] = []
567 
568  patternStr2Chains[overallPatternStr].append(chain)
569 
570  numPatternStr2Chains = dict()
571  for key in patternStr2Chains.keys():
572  numPatternStr2Chains[key] = len(patternStr2Chains[key])
573 
574  sortedPatternStr2Chains = []
575  for w in sorted(numPatternStr2Chains, key=numPatternStr2Chains.get, reverse=True):
576  # if (len(patternStr2Chains[w]) >= 2):
577  # print(w, len(patternStr2Chains[w]))
578  sortedPatternStr2Chains.append((w, patternStr2Chains[w]))
579 
580  return patternStr2Chains, sortedPatternStr2Chains
581 
582 
583 def printOutSimplePatterns(VivadoGraph, singleCorePattern):
584  numSingleCorePattern = dict()
585  for key in singleCorePattern.keys():
586  numSingleCorePattern[key] = len(singleCorePattern[key])
587 
588  for w in sorted(numSingleCorePattern, key=numSingleCorePattern.get, reverse=True):
589 
590  nodeInPattern = set()
591  overlappedSet = set()
592  for curnode, neighbornodes in singleCorePattern[w]:
593  nodeInPattern = nodeInPattern | neighbornodes
594 
595  for curNodeIdX, (curnodeX, neighbornodesX) in enumerate(singleCorePattern[w]):
596  for curNodeIdY, (curnodeY, neighbornodesY) in enumerate(singleCorePattern[w]):
597  if (curNodeIdX <= curNodeIdY):
598  break
599  overlappedSet = overlappedSet | (
600  neighbornodesX & neighbornodesY)
601 
602  cnt = 0
603  for comp in nx.algorithms.weakly_connected_components(VivadoGraph.subgraph(nodeInPattern)):
604  cnt += 1
605 
606  if (numSingleCorePattern[w] <= 1):
607  continue
608 
609  print("pattern: ", w, ":", numSingleCorePattern[w], ":", cnt)
610  print(" overlap nodes:")
611  for nodeId in overlappedSet:
612  print(" nodeName:", VivadoGraph.nodes()[nodeId]['name'], "type", VivadoGraph.nodes()[
613  nodeId]['type'], "degree", VivadoGraph.degree(nodeId))
614  print(" anchor nodes:")
615  for curnode, neighbornodes in singleCorePattern[w]:
616  print(" nodeName:",
617  curnode['name'], " id:", curnode['id'], "type: ", curnode['type'])
618  for nNode in neighbornodes:
619  print(" NeighborNodeName:", VivadoGraph.nodes()[
620  nNode]['name'], " id:", VivadoGraph.nodes()[nNode]['id'], "type: ", VivadoGraph.nodes()[nNode]['type'])
621  for nodeId in neighbornodes:
622  print(
623  " highlight_objects -color red [get_cells ", VivadoGraph.nodes()[nodeId]['name'], "]")
624 
625 
626 def printOutChainPatterns(VivadoGraph, patternStr2Chains):
627 
628  print("======================================\nprinting out chains' patterns")
629 
630  numpatternStr2Chains = dict()
631  for key in patternStr2Chains.keys():
632  numpatternStr2Chains[key] = len(patternStr2Chains[key])
633 
634  for w in sorted(numpatternStr2Chains, key=numpatternStr2Chains.get, reverse=True):
635 
636  nodeInPattern = set()
637  overlappedSet = set()
638  for chain in patternStr2Chains[w]:
639  nodeInPattern = nodeInPattern | chain.nodeInCluster
640 
641  for curChainIdX, curChainX in enumerate(patternStr2Chains[w]):
642  for curChainIdY, curChainY in enumerate(patternStr2Chains[w]):
643  if (curChainIdX <= curChainIdY):
644  break
645  overlappedSet = overlappedSet | (
646  curChainX.nodeInCluster & curChainY.nodeInCluster)
647 
648  cnt = 0
649  for comp in nx.algorithms.weakly_connected_components(VivadoGraph.subgraph(nodeInPattern)):
650  cnt += 1
651 
652  if (numpatternStr2Chains[w] <= 1):
653  continue
654 
655  print("pattern: ", w, ":", numpatternStr2Chains[w], ":", cnt)
656  for comp in nx.algorithms.weakly_connected_components(VivadoGraph.subgraph(nodeInPattern)):
657  for nodeId in comp:
658  print(
659  " highlight_objects -color red [get_cells ", VivadoGraph.nodes()[nodeId]['name'], "]")
660  break
661  print(" overlap nodes:")
662  for nodeId in overlappedSet:
663  print(" nodeName:", VivadoGraph.nodes()[nodeId]['name'], "type", VivadoGraph.nodes()[
664  nodeId]['type'], "degree", VivadoGraph.degree(nodeId))
665  print(" anchor chains:")
666  for chain in patternStr2Chains[w]:
667  print(" coreNodes:", chain.coreNodes)
668  for nodeId in chain.coreNodes:
669  print(" ", VivadoGraph.nodes()
670  [nodeId]['name'], " id:", nodeId)
671  for nodeId in chain.coreNodes:
672  print(
673  " highlight_objects -color red [get_cells ", VivadoGraph.nodes()[nodeId]['name'], "]")
674 
675 
676 def instantiatePatternClusters(VivadoGraph, sortedSingleCorePattern, lastClusterId):
677  res = []
678  clusterColorIdInitial = dict()
679  for node in VivadoGraph.nodes():
680  clusterColorIdInitial[node] = -1
681  nx.set_node_attributes(
682  G=VivadoGraph, values=clusterColorIdInitial, name="clusterColorId")
683 
684  for w, seqs in sortedSingleCorePattern:
685  patternClusters = []
686  if (len(seqs) == 0):
687  assert(False)
688  if (isinstance(seqs[0], VivadoCoreCluster)):
689  for chain in seqs:
690  unextendedNodes = set(chain.nodeInCluster)-set(chain.coreNodes)
691  extendedNodes = set(chain.coreNodes)
692  if (len(unextendedNodes) == 0):
693  unextendedNodes = extendedNodes
694  patternClusters.append(VivadoPatternCluster(initPatternStr=chain.patternStr,
695  unextendedNodes=unextendedNodes, extendedNodes=extendedNodes, clusterId=lastClusterId))
696  for nodeInSet in patternClusters[-1].extendedNodes | patternClusters[-1].unextendedNodes:
697  if (VivadoGraph.nodes()[nodeInSet]['clusterColorId'] < 0):
698  VivadoGraph.nodes()[
699  nodeInSet]['clusterColorId'] = lastClusterId
700  lastClusterId += 1
701  else:
702  for curNode, neighborNodes in seqs:
703  unextendedNodes = set(neighborNodes)-set([curNode['id']])
704  extendedNodes = set([curNode['id']])
705  if (len(unextendedNodes) == 0):
706  unextendedNodes = extendedNodes
707  patternClusters.append(VivadoPatternCluster(
708  initPatternStr=w, unextendedNodes=unextendedNodes, extendedNodes=extendedNodes, clusterId=lastClusterId))
709  for nodeInSet in patternClusters[-1].extendedNodes | patternClusters[-1].unextendedNodes:
710  if (VivadoGraph.nodes()[nodeInSet]['clusterColorId'] < 0):
711  VivadoGraph.nodes()[
712  nodeInSet]['clusterColorId'] = lastClusterId
713  lastClusterId += 1
714  res.append(VivadoPatternClusterSeq(
715  initPatternStr=w, patternClusters=patternClusters))
716 
717  return res, lastClusterId
718 
719 
721  pass
722  # for pattern in Patterns:
723  # for cluster in pattern:
724  # accumulateInterconnectionForceAmongNodes(cluster)
725 
726 
727 def printOutPatterns(patterns):
728  print("printOutPatterns:")
729  cntSum = 0
730  for curPatternSeq in patterns:
731  print(curPatternSeq.patternExtensionTrace.replace("\'", "").replace("\\", ""), len(curPatternSeq.patternClusters), len(
732  curPatternSeq.patternClusters[0].extendedNodes | curPatternSeq.patternClusters[0].unextendedNodes))
733  cntSum += len(curPatternSeq.patternClusters)
734  print("Total Clusters:", cntSum)
735  return cntSum
736 
737 
738 def BFSCheckEdgeAttributes(VivadoGraph, VivadoCells, curCell):
739  edgeAttributeCnt = dict()
740  cellQ = [curCell]
741  depQ = [0]
742  visitedSet = {curCell}
743  nextSet = set([curCell])
744 
745  while (len(cellQ) > 0):
746  curCell = cellQ.pop()
747  curDepth = depQ.pop()
748  visitedSet.add(curCell)
749 
750  if(curDepth >= 5):
751  continue
752 
753  # if (len(set(VivadoGraph.successors(curCell)))<4):
754  # for succ in VivadoGraph.successors(curCell):
755  # if (not (succ in nextSet)):
756  # if (VivadoGraph[curCell][succ]['driverPinType'].find("[")>=0):
757  # if (VivadoGraph[curCell][succ]['driverPinType'] in edgeAttributeCnt.keys()):
758  # edgeAttributeCnt[VivadoGraph[curCell][succ]['driverPinType']] += 1
759  # else:
760  # edgeAttributeCnt[VivadoGraph[curCell][succ]['driverPinType']] = 1
761  # else:
762  # nextSet.add(succ)
763  # depQ.append(curDepth+1)
764  # cellQ.append(succ)
765  if (len(set(VivadoGraph.predecessors(curCell))) < 32):
766  for pred in VivadoGraph.predecessors(curCell):
767  if (not (pred in nextSet)):
768  if (VivadoGraph[pred][curCell]['driverPinType'].find("[") >= 0):
769  if (VivadoGraph[pred][curCell]['driverPinType'] in edgeAttributeCnt.keys()):
770  edgeAttributeCnt[VivadoGraph[pred]
771  [curCell]['driverPinType']] += 1
772  else:
773  edgeAttributeCnt[VivadoGraph[pred]
774  [curCell]['driverPinType']] = 1
775  else:
776  nextSet.add(pred)
777  depQ.append(curDepth+1)
778  cellQ.append(pred)
779 
780  sortedEdgeAttributeCnt = []
781  for w in sorted(edgeAttributeCnt, key=edgeAttributeCnt.get, reverse=True):
782  sortedEdgeAttributeCnt.append((w, edgeAttributeCnt[w]))
783 
784  if (len(sortedEdgeAttributeCnt) > 4):
785  sortedEdgeAttributeCnt = sortedEdgeAttributeCnt[:4]
786  return sortedEdgeAttributeCnt
787 
788 
789 def loadClusters(name2id, clusterFileName):
790  clusters = []
791  id2cluster = dict()
792  clusterCnt = 0
793  clusterFile = open(clusterFileName, "r")
794 
795  for line in clusterFile.readlines():
796  clusterCellNames = line.split(" ")
797  ids = set()
798  for name in clusterCellNames:
799  if (name != ""):
800  if (name in name2id.keys()):
801  ids.add(name2id[name])
802  id2cluster[name2id[name]] = clusterCnt
803  clusterCnt += 1
804  clusters.append(ids)
805  return clusters, id2cluster
806 
807 
808 def loadClocks(clockFileName):
809  clockNames = []
810  clusterFile = open(clockFileName, "r")
811  for line in clusterFile.readlines():
812  clockNames.append(line.replace("\n", "").replace("/O", ""))
813  return clockNames
814 
815 
816 def loadFixedBlocks(fixedUnitFileName):
817  fixedUnitNames = []
818  fixedUnitFile = open(fixedUnitFileName, "r")
819  for line in fixedUnitFile.readlines():
820  fixedUnitNames.append(line.replace("\n", "").split(" ")[1])
821  return fixedUnitNames
VivadoGraphUtil.instantiatePatternClusters
def instantiatePatternClusters(VivadoGraph, sortedSingleCorePattern, lastClusterId)
Definition: VivadoGraphUtil.py:676
VivadoGraphUtil.VivadoCell
Definition: VivadoGraphUtil.py:4
VivadoGraphUtil.VivadoPin.name
name
Definition: VivadoGraphUtil.py:34
VivadoGraphUtil.chainBFS
def chainBFS(VivadoGraph, nodeId)
Definition: VivadoGraphUtil.py:318
VivadoGraphUtil.getInitalSingleCorePatterns
def getInitalSingleCorePatterns(VivadoGraph, careTypeList, coreType="CARRY", checkDirection="both", allowOverlap=True, onlyRecordInput=False)
Definition: VivadoGraphUtil.py:217
VivadoGraphUtil.clusterNodeChain
def clusterNodeChain(VivadoGraph, coreType="CARRY8")
Definition: VivadoGraphUtil.py:342
VivadoGraphUtil.VivadoPatternCluster.clusterId
clusterId
Definition: VivadoGraphUtil.py:63
VivadoGraphUtil.VivadoCoreCluster.coreNodes
coreNodes
Definition: VivadoGraphUtil.py:51
VivadoGraphUtil.printOutPatterns
def printOutPatterns(patterns)
Definition: VivadoGraphUtil.py:727
VivadoGraphUtil.VivadoCoreCluster.__init__
def __init__(self, coreType, coreNodes, patternStr, nodeInCluster)
Definition: VivadoGraphUtil.py:49
VivadoGraphUtil.printOutChainPatterns
def printOutChainPatterns(VivadoGraph, patternStr2Chains)
Definition: VivadoGraphUtil.py:626
VivadoGraphUtil.VivadoPatternCluster.extendedNodes
extendedNodes
Definition: VivadoGraphUtil.py:61
VivadoGraphUtil.VivadoPin
Definition: VivadoGraphUtil.py:32
VivadoGraphUtil.VivadoNet.name
name
Definition: VivadoGraphUtil.py:43
VivadoGraphUtil.VivadoPin.nameOnCell
nameOnCell
Definition: VivadoGraphUtil.py:38
VivadoGraphUtil.VivadoPatternClusterSeq.patternClusters
patternClusters
Definition: VivadoGraphUtil.py:70
VivadoGraphUtil.VivadoPin.__init__
def __init__(self, name, refName, nameOnCell, dir, cell)
Definition: VivadoGraphUtil.py:33
VivadoGraphUtil.VivadoNet.outputpins
outputpins
Definition: VivadoGraphUtil.py:45
VivadoGraphUtil.VivadoGraphExctractionAndInitialPatternDetect
def VivadoGraphExctractionAndInitialPatternDetect(VivadoCells)
Definition: VivadoGraphUtil.py:149
VivadoGraphUtil.printOutSimplePatterns
def printOutSimplePatterns(VivadoGraph, singleCorePattern)
Definition: VivadoGraphUtil.py:583
VivadoGraphUtil.VivadoCell.drivepinStr
drivepinStr
Definition: VivadoGraphUtil.py:11
VivadoGraphUtil.VivadoPatternCluster
Definition: VivadoGraphUtil.py:56
VivadoGraphUtil.BFSCheckEdgeAttributes
def BFSCheckEdgeAttributes(VivadoGraph, VivadoCells, curCell)
Definition: VivadoGraphUtil.py:738
VivadoGraphUtil.clusterExtendPatterns
def clusterExtendPatterns(VivadoGraph, chains, largeCluserIntoPattern=False, allowOverlap=False, largeCluserThredhold=2)
Definition: VivadoGraphUtil.py:453
VivadoGraphUtil.VivadoCell.id
id
Definition: VivadoGraphUtil.py:6
VivadoGraphUtil.VivadoPatternCluster.__init__
def __init__(self, initPatternStr, unextendedNodes, extendedNodes, clusterId)
Definition: VivadoGraphUtil.py:57
VivadoGraphUtil.VivadoPatternCluster.unextendedNodes
unextendedNodes
Definition: VivadoGraphUtil.py:60
VivadoGraphUtil.VivadoPin.cell
cell
Definition: VivadoGraphUtil.py:36
VivadoGraphUtil.clusterNodeWithCommonFanin
def clusterNodeWithCommonFanin(VivadoGraph, VivadoCells, targetType="RAM32M16")
Definition: VivadoGraphUtil.py:359
VivadoGraphUtil.VivadoPin.refName
refName
Definition: VivadoGraphUtil.py:37
VivadoGraphUtil.VivadoCoreCluster.nodeInCluster
nodeInCluster
Definition: VivadoGraphUtil.py:53
VivadoGraphUtil.VivadoCell.refType
refType
Definition: VivadoGraphUtil.py:8
VivadoGraphUtil.VivadoCell.bindPinDriveObjs
def bindPinDriveObjs(self, pinName2Obj)
Definition: VivadoGraphUtil.py:14
VivadoGraphUtil.VivadoPatternClusterSeq.patternExtensionTrace
patternExtensionTrace
Definition: VivadoGraphUtil.py:68
VivadoGraphUtil.VivadoCell.drivepins_fromOthers
drivepins_fromOthers
Definition: VivadoGraphUtil.py:12
VivadoGraphUtil.loadCellInfoFromFile
def loadCellInfoFromFile(textFile)
Definition: VivadoGraphUtil.py:73
VivadoGraphUtil.VivadoPin.dir
dir
Definition: VivadoGraphUtil.py:35
VivadoGraphUtil.VivadoCoreCluster.coreType
coreType
Definition: VivadoGraphUtil.py:50
VivadoGraphUtil.VivadoPatternCluster.disabled
disabled
Definition: VivadoGraphUtil.py:62
VivadoGraphUtil.VivadoNet.__init__
def __init__(self, name, inputpins, outputpins)
Definition: VivadoGraphUtil.py:42
VivadoGraphUtil.VivadoCell.__init__
def __init__(self, id, name, refType, pins, netStr, drivepinStr)
Definition: VivadoGraphUtil.py:5
VivadoGraphUtil.VivadoCell.netStr
netStr
Definition: VivadoGraphUtil.py:10
VivadoGraphUtil.VivadoCoreCluster.patternStr
patternStr
Definition: VivadoGraphUtil.py:52
VivadoGraphUtil.VivadoCell.drivepins
drivepins
Definition: VivadoGraphUtil.py:15
VivadoGraphUtil.VivadoCell.name
name
Definition: VivadoGraphUtil.py:7
VivadoGraphUtil.VivadoPatternClusterSeq
Definition: VivadoGraphUtil.py:66
VivadoGraphUtil.VivadoPatternCluster.patternExtensionTrace
patternExtensionTrace
Definition: VivadoGraphUtil.py:58
VivadoGraphUtil.VivadoPatternClusterSeq.__init__
def __init__(self, initPatternStr, patternClusters)
Definition: VivadoGraphUtil.py:67
VivadoGraphUtil.loadFixedBlocks
def loadFixedBlocks(fixedUnitFileName)
Definition: VivadoGraphUtil.py:816
VivadoGraphUtil.VivadoNet
Definition: VivadoGraphUtil.py:41
VivadoGraphUtil.loadClocks
def loadClocks(clockFileName)
Definition: VivadoGraphUtil.py:808
VivadoGraphUtil.VivadoCoreCluster
Definition: VivadoGraphUtil.py:48
VivadoGraphUtil.accumulateClusterForce
def accumulateClusterForce(Patterns)
Definition: VivadoGraphUtil.py:720
VivadoGraphUtil.VivadoNet.inputpins
inputpins
Definition: VivadoGraphUtil.py:44
VivadoGraphUtil.loadClusters
def loadClusters(name2id, clusterFileName)
Definition: VivadoGraphUtil.py:789
VivadoGraphUtil.VivadoCell.pins
pins
Definition: VivadoGraphUtil.py:9