|
|
|
@ -314,6 +314,28 @@ class Circuit:
@@ -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:
@@ -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:
@@ -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)) |
|
|
|
|
|
|
|
|
|