|
|
|
@ -614,19 +614,23 @@ class Circuit: |
|
|
|
if marks[n]: |
|
|
|
if marks[n]: |
|
|
|
yield n |
|
|
|
yield n |
|
|
|
|
|
|
|
|
|
|
|
def fanout(self, origin_nodes): |
|
|
|
def fanout(self, origin_nodes: list[Node], node_filter = lambda n: 'dff' not in n.name.lower()): |
|
|
|
"""Generator function to iterate over the fan-out cone of a given list of origin nodes. |
|
|
|
"""Generator function to iterate over the fan-out cone of a given list of origin nodes. |
|
|
|
|
|
|
|
|
|
|
|
Nodes are yielded in topological order. |
|
|
|
origin_nodes are yielded first, followed by nodes driven by them in a breadth-first manner. |
|
|
|
|
|
|
|
The search stops at nodes for which node_filter returns False. |
|
|
|
|
|
|
|
Only origin_nodes and nodes for which node_filter returned True are yielded. |
|
|
|
|
|
|
|
By default, search stops at flip-flops. |
|
|
|
""" |
|
|
|
""" |
|
|
|
marks = [False] * len(self.nodes) |
|
|
|
queue = deque(origin_nodes) |
|
|
|
for n in origin_nodes: |
|
|
|
yielded = set() |
|
|
|
marks[n] = True |
|
|
|
while len(queue) > 0: |
|
|
|
for n in self.topological_order(): |
|
|
|
n = queue.popleft() |
|
|
|
if not marks[n]: |
|
|
|
for line in n.outs.without_nones(): |
|
|
|
for line in n.ins.without_nones(): |
|
|
|
succ = line.reader |
|
|
|
marks[n] |= marks[line.driver] |
|
|
|
if succ not in yielded and node_filter(succ): |
|
|
|
if marks[n]: |
|
|
|
yielded.add(succ) |
|
|
|
|
|
|
|
queue.append(succ) |
|
|
|
yield n |
|
|
|
yield n |
|
|
|
|
|
|
|
|
|
|
|
def fanout_free_regions(self): |
|
|
|
def fanout_free_regions(self): |
|
|
|
|