From c32584fc76a7026e19da40047732d62c9903a024 Mon Sep 17 00:00:00 2001 From: Stefan Holst Date: Wed, 5 Jul 2023 22:55:06 +0900 Subject: [PATCH] 1to1 fork optimization, fix substitute --- src/kyupy/circuit.py | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/kyupy/circuit.py b/src/kyupy/circuit.py index b81904a..e039ebc 100644 --- a/src/kyupy/circuit.py +++ b/src/kyupy/circuit.py @@ -314,6 +314,28 @@ class Circuit: def get_or_add_fork(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): """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 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_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_out_lines) == len(impl_out_lines) in_lines_map = dict(zip(impl_in_lines, node_in_lines)) @@ -338,14 +360,16 @@ class Circuit: for l in impl.lines: if l in in_lines_map: ll = in_lines_map[l] - ll.reader = node_map[l.reader] - ll.reader_pin = l.reader_pin - ll.reader.ins[ll.reader_pin] = ll + if ll is not None: + ll.reader = node_map[l.reader] + ll.reader_pin = l.reader_pin + ll.reader.ins[ll.reader_pin] = ll elif l in out_lines_map: ll = out_lines_map[l] - ll.driver = node_map[l.driver] - ll.driver_pin = l.driver_pin - ll.driver.outs[ll.driver_pin] = ll + if ll is not None: + ll.driver = node_map[l.driver] + ll.driver_pin = l.driver_pin + ll.driver.outs[ll.driver_pin] = ll else: Line(self, (node_map[l.driver], l.driver_pin), (node_map[l.reader], l.reader_pin))