|
|
|
@ -314,6 +314,16 @@ class Circuit:
@@ -314,6 +314,16 @@ class Circuit:
|
|
|
|
|
def get_or_add_fork(self, name): |
|
|
|
|
return self.forks[name] if name in self.forks else Node(self, name) |
|
|
|
|
|
|
|
|
|
def remove_dangling_nodes(self, root_node:Node): |
|
|
|
|
if len([l for l in root_node.outs if l is not None]) > 0: return |
|
|
|
|
lines = [l for l in root_node.ins if l is not None] |
|
|
|
|
drivers = [l.driver for l in lines] |
|
|
|
|
root_node.remove() |
|
|
|
|
for l in lines: |
|
|
|
|
l.remove() |
|
|
|
|
for d in drivers: |
|
|
|
|
self.remove_dangling_nodes(d) |
|
|
|
|
|
|
|
|
|
def eliminate_1to1_forks(self): |
|
|
|
|
"""Removes all forks that drive only one node. |
|
|
|
|
|
|
|
|
@ -356,8 +366,6 @@ class Circuit:
@@ -356,8 +366,6 @@ class Circuit:
|
|
|
|
|
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)) |
|
|
|
|
out_lines_map = dict(zip(impl_out_lines, node_out_lines)) |
|
|
|
|
node.remove() |
|
|
|
|
node_map = dict() |
|
|
|
|
ios = set(impl.io_nodes) |
|
|
|
@ -370,13 +378,16 @@ class Circuit:
@@ -370,13 +378,16 @@ class Circuit:
|
|
|
|
|
for l in impl.lines: # add all internal lines to main circuit |
|
|
|
|
if l.reader in node_map and l.driver in node_map: |
|
|
|
|
Line(self, (node_map[l.driver], l.driver_pin), (node_map[l.reader], l.reader_pin)) |
|
|
|
|
for l, ll in in_lines_map.items(): # connect inputs |
|
|
|
|
for l, ll in zip(impl_in_lines, node_in_lines): # connect inputs |
|
|
|
|
if ll is None: continue |
|
|
|
|
ll.reader = node_map[l.reader] |
|
|
|
|
ll.reader_pin = l.reader_pin |
|
|
|
|
ll.reader.ins[ll.reader_pin] = ll |
|
|
|
|
for l, ll in out_lines_map.items(): # connect outputs |
|
|
|
|
if ll is None: continue |
|
|
|
|
for l, ll in zip(impl_out_lines, node_out_lines): # connect outputs |
|
|
|
|
if ll is None: |
|
|
|
|
if l.driver in node_map: |
|
|
|
|
self.remove_dangling_nodes(node_map[l.driver]) |
|
|
|
|
continue |
|
|
|
|
if len(l.reader.outs) > 0: # output is also read by impl. circuit, connect to fork. |
|
|
|
|
ll.driver = node_map[l.reader] |
|
|
|
|
ll.driver_pin = len(l.reader.outs) |
|
|
|
@ -385,6 +396,13 @@ class Circuit:
@@ -385,6 +396,13 @@ class Circuit:
|
|
|
|
|
ll.driver_pin = l.driver_pin |
|
|
|
|
ll.driver.outs[ll.driver_pin] = ll |
|
|
|
|
|
|
|
|
|
def resolve_tlib_cells(self, tlib): |
|
|
|
|
"""Substitute all technology library cells with kyupy native simulation primitives. |
|
|
|
|
""" |
|
|
|
|
for n in list(self.nodes): |
|
|
|
|
if n.kind in tlib.cells:# and 'DFF' not in n.kind and 'LATCH' not in n.kind: |
|
|
|
|
self.substitute(n, tlib.cells[n.kind][0]) |
|
|
|
|
|
|
|
|
|
def copy(self): |
|
|
|
|
"""Returns a deep copy of the circuit. |
|
|
|
|
""" |
|
|
|
|