Browse Source

1to1 fork optimization, fix substitute

devel
Stefan Holst 1 year ago
parent
commit
c32584fc76
  1. 40
      src/kyupy/circuit.py

40
src/kyupy/circuit.py

@ -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))

Loading…
Cancel
Save