Browse Source

move resolving cells to circuit, more doc

devel
Stefan Holst 1 year ago
parent
commit
d3897246c5
  1. 28
      src/kyupy/circuit.py
  2. 5
      src/kyupy/sdf.py
  3. 5
      src/kyupy/techlib.py

28
src/kyupy/circuit.py

@ -314,6 +314,16 @@ 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 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): def eliminate_1to1_forks(self):
"""Removes all forks that drive only one node. """Removes all forks that drive only one node.
@ -356,8 +366,6 @@ class Circuit:
node_out_lines = list(node.outs) + [None] * (len(impl_out_lines)-len(node.outs)) 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))
out_lines_map = dict(zip(impl_out_lines, node_out_lines))
node.remove() node.remove()
node_map = dict() node_map = dict()
ios = set(impl.io_nodes) ios = set(impl.io_nodes)
@ -370,13 +378,16 @@ class Circuit:
for l in impl.lines: # add all internal lines to main 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: 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)) 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 if ll is None: continue
ll.reader = node_map[l.reader] ll.reader = node_map[l.reader]
ll.reader_pin = l.reader_pin ll.reader_pin = l.reader_pin
ll.reader.ins[ll.reader_pin] = ll ll.reader.ins[ll.reader_pin] = ll
for l, ll in out_lines_map.items(): # connect outputs for l, ll in zip(impl_out_lines, node_out_lines): # connect outputs
if ll is None: continue 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. if len(l.reader.outs) > 0: # output is also read by impl. circuit, connect to fork.
ll.driver = node_map[l.reader] ll.driver = node_map[l.reader]
ll.driver_pin = len(l.reader.outs) ll.driver_pin = len(l.reader.outs)
@ -385,6 +396,13 @@ class Circuit:
ll.driver_pin = l.driver_pin ll.driver_pin = l.driver_pin
ll.driver.outs[ll.driver_pin] = ll 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): def copy(self):
"""Returns a deep copy of the circuit. """Returns a deep copy of the circuit.
""" """

5
src/kyupy/sdf.py

@ -40,8 +40,11 @@ class DelayFile:
All IOPATH delays for a node ``n`` are annotated to the line connected to the input pin specified in the IOPATH. All IOPATH delays for a node ``n`` are annotated to the line connected to the input pin specified in the IOPATH.
Only supports two delvals per delval_list. First delval is rising/posedge, second delval is falling/negedge Limited support of SDF spec:
* ABSOLUTE delay values only
* two delvals per delval_list. First is rising/posedge, second is falling/negedge
transition at the output of the IOPATH (SDF spec, pp. 3-17). transition at the output of the IOPATH (SDF spec, pp. 3-17).
* PATHPULSE declarations are ignored.
* Axis 0: dataset (usually 3 datasets per SDF-file) * Axis 0: dataset (usually 3 datasets per SDF-file)
* Axis 1: line index (e.g. ``n.ins[0]``, ``n.ins[1]``) * Axis 1: line index (e.g. ``n.ins[0]``, ``n.ins[1]``)

5
src/kyupy/techlib.py

@ -128,11 +128,6 @@ class TechLibNew:
def pin_is_output(self, kind, pin): def pin_is_output(self, kind, pin):
return self.cells[kind][1][pin][1] return self.cells[kind][1][pin][1]
def resolve(self, circuit):
for n in list(circuit.nodes):
if n.kind in self.cells:
circuit.substitute(n, self.cells[n.kind][0])
NANGATE = TechLibNew(r""" NANGATE = TechLibNew(r"""
FILLCELL_X{1,2,4,8,16,32} ; FILLCELL_X{1,2,4,8,16,32} ;

Loading…
Cancel
Save