circuit node substitution
This commit is contained in:
1 parent
f8bf579be2
commit
670fb0b3fc
3 files changed
+73
-3
No files matched your search
@@ -314,6 +314,41 @@ 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 substitute(self, node, impl):
|
||||||
|
"""Replaces a given node with the given implementation circuit.
|
||||||
|
|
||||||
|
The given node will be removed, the implementation is copied in and
|
||||||
|
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]
|
||||||
|
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)
|
||||||
|
for n in impl.nodes:
|
||||||
|
if n not in ios:
|
||||||
|
node_map[n] = Node(self, node.name + '~' + n.name, n.kind)
|
||||||
|
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
|
||||||
|
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
|
||||||
|
else:
|
||||||
|
Line(self, (node_map[l.driver], l.driver_pin), (node_map[l.reader], l.reader_pin))
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
"""Returns a deep copy of the circuit.
|
"""Returns a deep copy of the circuit.
|
||||||
"""
|
"""
|
||||||
|
|||||||
+18
-1
@@ -1,5 +1,5 @@
|
|||||||
from .circuit import Node, Line
|
from .circuit import Node, Line
|
||||||
|
from . import bench
|
||||||
|
|
||||||
def add_and_connect(circuit, name, kind, in1=None, in2=None, out=None):
|
def add_and_connect(circuit, name, kind, in1=None, in2=None, out=None):
|
||||||
n = Node(circuit, name, kind)
|
n = Node(circuit, name, kind)
|
||||||
@@ -66,6 +66,23 @@ class TechLib:
|
|||||||
if 'MUX' in kind and pin == 'S': return False
|
if 'MUX' in kind and pin == 'S': return False
|
||||||
return pin in ('Q', 'QN', 'Z', 'ZN', 'Y', 'CO', 'S', 'SO', 'C1')
|
return pin in ('Q', 'QN', 'Z', 'ZN', 'Y', 'CO', 'S', 'SO', 'C1')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def substitute_nonsim_cells(circuit):
|
||||||
|
tmap = {'ISOLAND': bench.parse('input(iso, d) output(q) not_iso=not(iso) q=and(not_iso, d)'),
|
||||||
|
'AO221' : bench.parse('input(in1, in2, in3, in4, in5) output(q) a=ao22(in1, in2, in3, in4) q=or(a, in5)'),
|
||||||
|
'AOI221' : bench.parse('input(in1, in2, in3, in4, in5) output(qn) a=ao22(in1, in2, in3, in4) qn=nor(a, in5)'),
|
||||||
|
'OA221' : bench.parse('input(in1, in2, in3, in4, in5) output(q) a=oa22(in1, in2, in3, in4) q=and(a, in5)'),
|
||||||
|
'OAI221' : bench.parse('input(in1, in2, in3, in4, in5) output(qn) a=oa22(in1, in2, in3, in4) qn=nand(a, in5)'),
|
||||||
|
'AO222' : bench.parse('input(in1, in2, in3, in4, in5, in6) output(q) a=ao22(in1, in2, in3, in4) q=ao21(in5, in6, a)'),
|
||||||
|
'AOI222' : bench.parse('input(in1, in2, in3, in4, in5, in6) output(qn) a=ao22(in1, in2, in3, in4) qn=aoi21(in5, in6, a)'),
|
||||||
|
'OA222' : bench.parse('input(in1, in2, in3, in4, in5, in6) output(q) a=oa22(in1, in2, in3, in4) q=oa21(in5, in6, a)'),
|
||||||
|
'OAI222' : bench.parse('input(in1, in2, in3, in4, in5, in6) output(qn) a=oa22(in1, in2, in3, in4) qn=oai21(in5, in6, a)'),
|
||||||
|
}
|
||||||
|
for n in list(circuit.nodes):
|
||||||
|
for k, v in tmap.items():
|
||||||
|
if n.kind.startswith(k):
|
||||||
|
circuit.substitute(n, v)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def split_complex_gates(circuit):
|
def split_complex_gates(circuit):
|
||||||
node_list = circuit.nodes
|
node_list = circuit.nodes
|
||||||
|
|||||||
+20
-2
@@ -1,7 +1,8 @@
|
|||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
from kyupy.circuit import Circuit, Node, Line
|
from kyupy.circuit import Circuit, Node, Line
|
||||||
from kyupy import verilog
|
from kyupy import verilog, bench
|
||||||
|
from kyupy.techlib import TechLib
|
||||||
|
|
||||||
def test_lines():
|
def test_lines():
|
||||||
c = Circuit()
|
c = Circuit()
|
||||||
@@ -104,9 +105,26 @@ def test_circuit():
|
|||||||
|
|
||||||
|
|
||||||
def test_pickle(mydir):
|
def test_pickle(mydir):
|
||||||
c = verilog.load(mydir / 'b14.v.gz')
|
c = verilog.load(mydir / 'b15_4ig.v.gz')
|
||||||
assert c is not None
|
assert c is not None
|
||||||
cs = pickle.dumps(c)
|
cs = pickle.dumps(c)
|
||||||
assert cs is not None
|
assert cs is not None
|
||||||
c2 = pickle.loads(cs)
|
c2 = pickle.loads(cs)
|
||||||
assert c == c2
|
assert c == c2
|
||||||
|
|
||||||
|
def test_substitute():
|
||||||
|
c = bench.parse('input(i1, i2, i3, i4, i5) output(o1) aoi=AOI221(i1, i2, i3, i4, i5) o1=not(aoi)')
|
||||||
|
assert len(c.cells) == 2
|
||||||
|
assert len(c.io_nodes) == 6
|
||||||
|
aoi221_impl = bench.parse('input(in1, in2, in3, in4, in5) output(q) a1=and(in1, in2) a2=and(in3, in4) q=or(a1, a2, in5)')
|
||||||
|
assert len(aoi221_impl.cells) == 3
|
||||||
|
assert len(aoi221_impl.io_nodes) == 6
|
||||||
|
c.substitute(c.cells['aoi'], aoi221_impl)
|
||||||
|
assert len(c.cells) == 4
|
||||||
|
assert len(c.io_nodes) == 6
|
||||||
|
|
||||||
|
c = bench.parse('input(i1, i2, i3, i4, i5) output(o1) aoi221=AOI221(i1, i2, i3, i4, i5) o1=not(aoi221)')
|
||||||
|
assert len(c.cells) == 2
|
||||||
|
TechLib.substitute_nonsim_cells(c)
|
||||||
|
assert len(c.cells) == 3
|
||||||
|
print('\n'.join(map(str, c.nodes)))
|
||||||
Reference in new issue
Block a user