1to1 fork optimization, fix substitute
This commit is contained in:
1 parent
39b8c1695b
commit
c32584fc76
1 file changed
+32
-8
+32
-8
@@ -314,6 +314,28 @@ class Circuit:
|
|||||||
def get_or_add_fork(self, name):
|
def get_or_add_fork(self, name):
|
||||||
return self.forks[name] if name in self.forks else Node(self, name)
|
return self.forks[name] if name in self.forks else Node(self, name)
|
||||||
|
|
||||||
|
def eliminate_1to1_forks(self):
|
||||||
|
"""Removes all forks that drive only one node.
|
||||||
|
|
||||||
|
Such forks are inserted by parsers to annotate signal names. If this
|
||||||
|
information is not needed, such forks can be removed and the two neighbors
|
||||||
|
can be connected directly using one line. Forks that drive more than one node
|
||||||
|
are not removed by this function.
|
||||||
|
"""
|
||||||
|
ios = set(self.io_nodes)
|
||||||
|
for n in list(self.forks.values()):
|
||||||
|
if n in ios: continue
|
||||||
|
if len(n.outs) != 1: continue
|
||||||
|
in_line = n.ins[0]
|
||||||
|
out_line = n.outs[0]
|
||||||
|
out_reader = out_line.reader
|
||||||
|
out_reader_pin = out_line.reader_pin
|
||||||
|
n.remove()
|
||||||
|
out_line.remove()
|
||||||
|
in_line.reader = out_reader
|
||||||
|
in_line.reader_pin = out_reader_pin
|
||||||
|
in_line.reader.ins[in_line.reader_pin] = in_line
|
||||||
|
|
||||||
def substitute(self, node, impl):
|
def substitute(self, node, impl):
|
||||||
"""Replaces a given node with the given implementation circuit.
|
"""Replaces a given node with the given implementation circuit.
|
||||||
|
|
||||||
@@ -321,10 +343,10 @@ class Circuit:
|
|||||||
the signal lines are connected appropriately. The number and arrangement
|
the signal lines are connected appropriately. The number and arrangement
|
||||||
of the input and output ports must match the pins of the replaced node.
|
of the input and output ports must match the pins of the replaced node.
|
||||||
"""
|
"""
|
||||||
node_in_lines = [l for l in node.ins if l]
|
|
||||||
node_out_lines = [l for l in node.outs if l]
|
|
||||||
impl_in_lines = [n.outs[0] for n in impl.io_nodes if len(n.outs) > 0]
|
impl_in_lines = [n.outs[0] for n in impl.io_nodes if len(n.outs) > 0]
|
||||||
impl_out_lines = [n.ins[0] for n in impl.io_nodes if len(n.ins) > 0]
|
impl_out_lines = [n.ins[0] for n in impl.io_nodes if len(n.ins) > 0]
|
||||||
|
node_in_lines = list(node.ins) + [None] * (len(impl_in_lines)-len(node.ins))
|
||||||
|
node_out_lines = list(node.outs) + [None] * (len(impl_out_lines)-len(node.outs))
|
||||||
assert len(node_in_lines) == len(impl_in_lines)
|
assert len(node_in_lines) == len(impl_in_lines)
|
||||||
assert len(node_out_lines) == len(impl_out_lines)
|
assert len(node_out_lines) == len(impl_out_lines)
|
||||||
in_lines_map = dict(zip(impl_in_lines, node_in_lines))
|
in_lines_map = dict(zip(impl_in_lines, node_in_lines))
|
||||||
@@ -338,14 +360,16 @@ class Circuit:
|
|||||||
for l in impl.lines:
|
for l in impl.lines:
|
||||||
if l in in_lines_map:
|
if l in in_lines_map:
|
||||||
ll = in_lines_map[l]
|
ll = in_lines_map[l]
|
||||||
ll.reader = node_map[l.reader]
|
if ll is not None:
|
||||||
ll.reader_pin = l.reader_pin
|
ll.reader = node_map[l.reader]
|
||||||
ll.reader.ins[ll.reader_pin] = ll
|
ll.reader_pin = l.reader_pin
|
||||||
|
ll.reader.ins[ll.reader_pin] = ll
|
||||||
elif l in out_lines_map:
|
elif l in out_lines_map:
|
||||||
ll = out_lines_map[l]
|
ll = out_lines_map[l]
|
||||||
ll.driver = node_map[l.driver]
|
if ll is not None:
|
||||||
ll.driver_pin = l.driver_pin
|
ll.driver = node_map[l.driver]
|
||||||
ll.driver.outs[ll.driver_pin] = ll
|
ll.driver_pin = l.driver_pin
|
||||||
|
ll.driver.outs[ll.driver_pin] = ll
|
||||||
else:
|
else:
|
||||||
Line(self, (node_map[l.driver], l.driver_pin), (node_map[l.reader], l.reader_pin))
|
Line(self, (node_map[l.driver], l.driver_pin), (node_map[l.reader], l.reader_pin))
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user