5 def __init__(self, id, name, refType, pins, netStr, drivepinStr):
20 if ((tmpName
in pinName2Obj.keys())
and (
not pin
is None)):
21 self.
drivepins.append(pinName2Obj[tmpName])
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)
33 def __init__(self, name, refName, nameOnCell, dir, cell):
42 def __init__(self, name, inputpins, outputpins):
49 def __init__(self, coreType, coreNodes, patternStr, nodeInCluster):
57 def __init__(self, initPatternStr, unextendedNodes, extendedNodes, clusterId):
59 "\'",
"").replace(
"\\",
"")
67 def __init__(self, initPatternStr, patternClusters):
69 "\'",
"").replace(
"\\",
"")
81 for line
in textFile.decode(
'utf-8').split(
"\n"):
85 if (line.find(
"curCell=> ") >= 0):
88 if (
not (curCell
is None)):
89 if (
not curCell.name
in cellName2Obj.keys()):
90 VivadoCells.append(curCell)
91 cellName2Obj[curCell.name] = curCell
93 print(
"WARNING duplicate cell:", curCell.name)
96 name_type = line.replace(
"curCell=> ",
"").split(
" type=> ")
98 refType = name_type[1]
99 if (name
in cellName2Obj.keys()):
102 curCell =
VivadoCell(idCnt, name, refType, [], [], [])
107 if (line.find(
" pin=> ") >= 0):
108 if (curCell
is None):
110 pin_refpin_dir_net_drivepin = line.replace(
" pin=> ",
"").replace(
" refpin=> ",
";").replace(
111 " dir=> ",
";").replace(
" net=> ",
";").replace(
" drivepin=> ",
";").split(
";")
113 if (len(pin_refpin_dir_net_drivepin) > 5):
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",
""))
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)
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)
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)
133 if (curPin.name ==
""):
136 if (
not curPin.name
in pinName2Obj.keys()):
137 pinName2Obj[curPin.name] = curPin
138 curCell.pins.append(curPin)
140 VivadoCells.append(curCell)
141 cellName2Obj[curCell.name] = curCell
143 for curCell
in VivadoCells:
144 curCell.bindPinDriveObjs(pinName2Obj)
150 inputPatterns = dict()
151 inputPatterns_Cells = dict()
153 outputPatternCnt = dict()
157 netstr2Tuple = dict()
158 netstr2netnum = dict()
163 for tmpCell
in VivadoCells:
164 outputPatternCnt[tmpCell.id] = dict()
166 VivadoGraph = nx.DiGraph()
168 for tmpCell
in VivadoCells:
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)
176 if (not(tmpCell.refType
in cellTypes.keys())):
177 cellTypes[tmpCell.refType] = 0
178 cellTypes[tmpCell.refType] += 1
180 driverTypeCnt = dict()
183 for pin, net, drivepin
in zip(tmpCell.pins, tmpCell.netStr, tmpCell.drivepins):
185 if (
not (drivepin
is None)):
186 if (pin.dir
and net !=
""):
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
199 for key
in netstr2netnum.keys():
201 (netstr2Tuple[key][0], netstr2Tuple[key][1], netstr2netnum[key]))
203 VivadoGraph.add_weighted_edges_from(netlist)
205 for a, b, driverPinType
in edgeAttributes:
206 VivadoGraph[a][b][
'driverPinType'] = driverPinType
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())
219 careTypeList = set(careTypeList)
221 singleCorePattern =
None
223 if (checkDirection ==
"both"):
226 elif (checkDirection ==
"in"):
229 elif (checkDirection ==
"out"):
235 singleCorePattern = dict()
237 traversedNodes = set()
239 for nodeId
in VivadoGraph.nodes():
240 curNode = VivadoGraph.nodes()[nodeId]
242 nodeType = curNode[
'type']
243 if (nodeType.find(coreType) >= 0):
245 if ((nodeId
in traversedNodes)
and (
not allowOverlap)):
248 nodeInPattern = set()
249 nodeInPattern.add(nodeId)
250 traversedNodes.add(nodeId)
253 for pred
in VivadoGraph.predecessors(nodeId):
254 if ((pred
in traversedNodes)
and (
not allowOverlap)):
256 nodeInPattern.add(pred)
257 traversedNodes.add(pred)
258 predNode = VivadoGraph.nodes()[pred]
259 if (
not predNode[
'type']
in careTypeList):
261 if (
not (predNode[
'type']
in predTypeCnt.keys())):
262 predTypeCnt[predNode[
'type']] = 0
263 predTypeCnt[predNode[
'type']
264 ] += VivadoGraph[pred][nodeId][
'weight']
267 for key
in predTypeCnt.keys():
268 predTypeList.append(key+
"-"+str(predTypeCnt[key]))
270 predPatternStr =
'-'.join(predTypeList) +
">="
274 for succ
in VivadoGraph.successors(nodeId):
275 if ((succ
in traversedNodes)
and (
not allowOverlap)):
277 if (
not onlyRecordInput):
278 nodeInPattern.add(succ)
279 traversedNodes.add(succ)
280 succNode = VivadoGraph.nodes()[succ]
281 if (
not succNode[
'type']
in careTypeList):
283 if (
not (succNode[
'type']
in succTypeCnt.keys())):
284 succTypeCnt[succNode[
'type']] = 0
285 succTypeCnt[succNode[
'type']
286 ] += VivadoGraph[nodeId][succ][
'weight']
289 for key
in succTypeCnt.keys():
290 succTypeList.append(key+
"-"+str(succTypeCnt[key]))
292 succPatternStr =
">=" +
'-'.join(succTypeList)
294 overallPatternStr = predPatternStr + nodeType + succPatternStr
296 if (coreType ==
"MUXF7" and overallPatternStr.find(
"MUXF8") >= 0):
299 if (
not (overallPatternStr
in singleCorePattern.keys())):
300 singleCorePattern[overallPatternStr] = []
302 singleCorePattern[overallPatternStr].append(
303 (curNode, nodeInPattern))
305 numSingleCorePattern = dict()
306 for key
in singleCorePattern.keys():
307 numSingleCorePattern[key] = len(singleCorePattern[key])
309 sortedSingleCorePattern = []
310 for w
in sorted(numSingleCorePattern, key=numSingleCorePattern.get, reverse=
True):
313 sortedSingleCorePattern.append((w, singleCorePattern[w]))
315 return singleCorePattern, sortedSingleCorePattern
320 coreType = VivadoGraph.nodes()[nodeId][
'type']
323 curSet = set({curId})
325 while (len(curSet) > 0):
326 reachSet = reachSet | curSet
329 for succ
in VivadoGraph.successors(curId):
330 if (coreType == VivadoGraph.nodes()[succ][
'type']):
331 if (
not (succ
in reachSet)):
333 for pred
in VivadoGraph.predecessors(curId):
334 if (coreType == VivadoGraph.nodes()[pred][
'type']):
335 if (
not (pred
in reachSet)):
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):
352 coreNodes =
chainBFS(VivadoGraph, nodeId)
353 chainedSet = chainedSet | coreNodes
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)
370 graphForCluster = nx.Graph()
371 for nodeId
in allNodesInType:
372 graphForCluster.add_node(nodeId)
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)))
381 edges.sort(key=
lambda tup: tup[2], reverse=
True)
383 node2NumCommonFanin = dict()
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
394 if (node2NumCommonFanin[nodeA] == node2NumCommonFanin[nodeB]):
395 graphForCluster.add_edge(nodeA, nodeB)
403 if (
not nodeA
in clusteredSet):
404 overlapDriverPin =
None
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
415 if (overlapDriverPin == driverPins):
416 clusteredSet.add(nodeId)
417 newCluster.add(nodeId)
419 clusterSet_list.append(newCluster)
422 if (
not nodeB
in clusteredSet):
423 overlapDriverPin =
None
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
434 if (overlapDriverPin == driverPins):
435 clusteredSet.add(nodeId)
436 newCluster.add(nodeId)
438 clusterSet_list.append(newCluster)
443 for comp
in clusterSet_list:
453 def clusterExtendPatterns(VivadoGraph, chains, largeCluserIntoPattern=False, allowOverlap=False, largeCluserThredhold=2):
455 patternStr2Chains = dict()
456 traversedNodes = set()
460 corePatternStr = chain.coreType +
"-" + str(len(chain.coreNodes))
462 if (largeCluserIntoPattern
and len(chain.coreNodes) > largeCluserThredhold):
463 corePatternStr +=
"largeParallel("+str(largeCnt)+
")"
465 for nodeId
in chain.coreNodes:
467 if ((nodeId
in traversedNodes)
and (
not allowOverlap)):
469 traversedNodes.add(nodeId)
471 nodeInPattern = set([nodeId])
474 chain.coreType, set(),
None,
None)
510 overallPatternStr =
">=" + corePatternStr +
">="
511 newCluster.patternStr = overallPatternStr
512 newCluster.nodeInCluster = nodeInPattern
514 if (
not (overallPatternStr
in patternStr2Chains.keys())):
515 patternStr2Chains[overallPatternStr] = []
517 patternStr2Chains[overallPatternStr].append(newCluster)
520 nodeInPattern = chain.coreNodes.copy() - traversedNodes
523 for nodeId
in chain.coreNodes - traversedNodes:
524 for pred
in VivadoGraph.predecessors(nodeId):
525 if ((pred
in traversedNodes)
and (
not allowOverlap)):
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']
536 for key
in predTypeCnt.keys():
537 predTypeList.append(key+
"-"+str(predTypeCnt[key]))
539 predPatternStr =
'-'.join(predTypeList) +
">="
542 for nodeId
in chain.coreNodes - traversedNodes:
543 for succ
in VivadoGraph.successors(nodeId):
544 if ((succ
in traversedNodes)
and (
not allowOverlap)):
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']
555 for key
in succTypeCnt.keys():
556 succTypeList.append(key+
"-"+str(succTypeCnt[key]))
558 succPatternStr =
">=" +
'-'.join(succTypeList)
560 overallPatternStr = predPatternStr + corePatternStr + succPatternStr
562 chain.patternStr = overallPatternStr
563 chain.nodeInCluster = nodeInPattern
565 if (
not (overallPatternStr
in patternStr2Chains.keys())):
566 patternStr2Chains[overallPatternStr] = []
568 patternStr2Chains[overallPatternStr].append(chain)
570 numPatternStr2Chains = dict()
571 for key
in patternStr2Chains.keys():
572 numPatternStr2Chains[key] = len(patternStr2Chains[key])
574 sortedPatternStr2Chains = []
575 for w
in sorted(numPatternStr2Chains, key=numPatternStr2Chains.get, reverse=
True):
578 sortedPatternStr2Chains.append((w, patternStr2Chains[w]))
580 return patternStr2Chains, sortedPatternStr2Chains
584 numSingleCorePattern = dict()
585 for key
in singleCorePattern.keys():
586 numSingleCorePattern[key] = len(singleCorePattern[key])
588 for w
in sorted(numSingleCorePattern, key=numSingleCorePattern.get, reverse=
True):
590 nodeInPattern = set()
591 overlappedSet = set()
592 for curnode, neighbornodes
in singleCorePattern[w]:
593 nodeInPattern = nodeInPattern | neighbornodes
595 for curNodeIdX, (curnodeX, neighbornodesX)
in enumerate(singleCorePattern[w]):
596 for curNodeIdY, (curnodeY, neighbornodesY)
in enumerate(singleCorePattern[w]):
597 if (curNodeIdX <= curNodeIdY):
599 overlappedSet = overlappedSet | (
600 neighbornodesX & neighbornodesY)
603 for comp
in nx.algorithms.weakly_connected_components(VivadoGraph.subgraph(nodeInPattern)):
606 if (numSingleCorePattern[w] <= 1):
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]:
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:
623 " highlight_objects -color red [get_cells ", VivadoGraph.nodes()[nodeId][
'name'],
"]")
628 print(
"======================================\nprinting out chains' patterns")
630 numpatternStr2Chains = dict()
631 for key
in patternStr2Chains.keys():
632 numpatternStr2Chains[key] = len(patternStr2Chains[key])
634 for w
in sorted(numpatternStr2Chains, key=numpatternStr2Chains.get, reverse=
True):
636 nodeInPattern = set()
637 overlappedSet = set()
638 for chain
in patternStr2Chains[w]:
639 nodeInPattern = nodeInPattern | chain.nodeInCluster
641 for curChainIdX, curChainX
in enumerate(patternStr2Chains[w]):
642 for curChainIdY, curChainY
in enumerate(patternStr2Chains[w]):
643 if (curChainIdX <= curChainIdY):
645 overlappedSet = overlappedSet | (
646 curChainX.nodeInCluster & curChainY.nodeInCluster)
649 for comp
in nx.algorithms.weakly_connected_components(VivadoGraph.subgraph(nodeInPattern)):
652 if (numpatternStr2Chains[w] <= 1):
655 print(
"pattern: ", w,
":", numpatternStr2Chains[w],
":", cnt)
656 for comp
in nx.algorithms.weakly_connected_components(VivadoGraph.subgraph(nodeInPattern)):
659 " highlight_objects -color red [get_cells ", VivadoGraph.nodes()[nodeId][
'name'],
"]")
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:
673 " highlight_objects -color red [get_cells ", VivadoGraph.nodes()[nodeId][
'name'],
"]")
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")
684 for w, seqs
in sortedSingleCorePattern:
688 if (isinstance(seqs[0], VivadoCoreCluster)):
690 unextendedNodes = set(chain.nodeInCluster)-set(chain.coreNodes)
691 extendedNodes = set(chain.coreNodes)
692 if (len(unextendedNodes) == 0):
693 unextendedNodes = extendedNodes
695 unextendedNodes=unextendedNodes, extendedNodes=extendedNodes, clusterId=lastClusterId))
696 for nodeInSet
in patternClusters[-1].extendedNodes | patternClusters[-1].unextendedNodes:
697 if (VivadoGraph.nodes()[nodeInSet][
'clusterColorId'] < 0):
699 nodeInSet][
'clusterColorId'] = lastClusterId
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
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):
712 nodeInSet][
'clusterColorId'] = lastClusterId
715 initPatternStr=w, patternClusters=patternClusters))
717 return res, lastClusterId
728 print(
"printOutPatterns:")
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)
739 edgeAttributeCnt = dict()
742 visitedSet = {curCell}
743 nextSet = set([curCell])
745 while (len(cellQ) > 0):
746 curCell = cellQ.pop()
747 curDepth = depQ.pop()
748 visitedSet.add(curCell)
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
773 edgeAttributeCnt[VivadoGraph[pred]
774 [curCell][
'driverPinType']] = 1
777 depQ.append(curDepth+1)
780 sortedEdgeAttributeCnt = []
781 for w
in sorted(edgeAttributeCnt, key=edgeAttributeCnt.get, reverse=
True):
782 sortedEdgeAttributeCnt.append((w, edgeAttributeCnt[w]))
784 if (len(sortedEdgeAttributeCnt) > 4):
785 sortedEdgeAttributeCnt = sortedEdgeAttributeCnt[:4]
786 return sortedEdgeAttributeCnt
793 clusterFile = open(clusterFileName,
"r")
795 for line
in clusterFile.readlines():
796 clusterCellNames = line.split(
" ")
798 for name
in clusterCellNames:
800 if (name
in name2id.keys()):
801 ids.add(name2id[name])
802 id2cluster[name2id[name]] = clusterCnt
805 return clusters, id2cluster
810 clusterFile = open(clockFileName,
"r")
811 for line
in clusterFile.readlines():
812 clockNames.append(line.replace(
"\n",
"").replace(
"/O",
""))
818 fixedUnitFile = open(fixedUnitFileName,
"r")
819 for line
in fixedUnitFile.readlines():
820 fixedUnitNames.append(line.replace(
"\n",
"").split(
" ")[1])
821 return fixedUnitNames