|
|
|
@ -1,6 +1,7 @@
@@ -1,6 +1,7 @@
|
|
|
|
|
from .circuit import Node, Line |
|
|
|
|
from . import bench |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_and_connect(circuit, name, kind, in1=None, in2=None, out=None): |
|
|
|
|
n = Node(circuit, name, kind) |
|
|
|
|
if in1 is not None: |
|
|
|
@ -29,6 +30,8 @@ class TechLib:
@@ -29,6 +30,8 @@ class TechLib:
|
|
|
|
|
@staticmethod |
|
|
|
|
def pin_index(kind, pin): |
|
|
|
|
"""Returns a pin list position for a given node kind and pin name.""" |
|
|
|
|
if isinstance(pin, int): |
|
|
|
|
return max(0, pin-1) |
|
|
|
|
if kind[:3] in ('OAI', 'AOI'): |
|
|
|
|
if pin[0] == 'A': return int(pin[1]) - 1 |
|
|
|
|
if pin == 'B': return int(kind[3]) |
|
|
|
@ -63,6 +66,8 @@ class TechLib:
@@ -63,6 +66,8 @@ class TechLib:
|
|
|
|
|
@staticmethod |
|
|
|
|
def pin_is_output(kind, pin): |
|
|
|
|
"""Returns True, if given pin name of a node kind is an output.""" |
|
|
|
|
if isinstance(pin, int): |
|
|
|
|
return pin == 0 |
|
|
|
|
if 'MUX' in kind and pin == 'S': return False |
|
|
|
|
return pin in ('Q', 'QN', 'Z', 'ZN', 'Y', 'CO', 'S', 'SO', 'C1') |
|
|
|
|
|
|
|
|
@ -77,256 +82,15 @@ class TechLib:
@@ -77,256 +82,15 @@ class TechLib:
|
|
|
|
|
'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)'), |
|
|
|
|
'HADD' : bench.parse('input(a,b) output(s,co) co=xor(a,b) s=and(a,b)'), |
|
|
|
|
'FADD' : bench.parse('input(a,b,ci) output(s,co) ab=xor(a,b) co=xor(ab,ci) s=ao22(ab,ci,a,b)'), |
|
|
|
|
} |
|
|
|
|
for n in list(circuit.nodes): |
|
|
|
|
if n.kind.startswith('DFFSSR'): |
|
|
|
|
n.kind = 'DFFX1' |
|
|
|
|
n_and0 = add_and_connect(circuit, n.name + '~and0', 'AND2', n.ins[0], n.ins[2], None) |
|
|
|
|
Line(circuit, n_and0, (n, 0)) |
|
|
|
|
else: |
|
|
|
|
for k, v in tmap.items(): |
|
|
|
|
if n.kind.startswith(k): |
|
|
|
|
circuit.substitute(n, v) |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def split_complex_gates(circuit): |
|
|
|
|
node_list = circuit.nodes |
|
|
|
|
for n in node_list: |
|
|
|
|
name = n.name |
|
|
|
|
ins = n.ins |
|
|
|
|
outs = n.outs |
|
|
|
|
if n.kind.startswith('AO21X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_and = add_and_connect(circuit, name+'~and', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n_or = add_and_connect(circuit, name+'~or', 'OR2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n_and, n_or) |
|
|
|
|
elif n.kind.startswith('AOI21X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_and = add_and_connect(circuit, name+'~and', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n_nor = add_and_connect(circuit, name+'~nor', 'NOR2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n_and, n_nor) |
|
|
|
|
elif n.kind.startswith('OA21X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_or = add_and_connect(circuit, name+'~or', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n_and = add_and_connect(circuit, name+'~and', 'AND2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n_or, n_and) |
|
|
|
|
elif n.kind.startswith('OAI21X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_or = add_and_connect(circuit, name+'~or', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n_nand = add_and_connect(circuit, name+'~nand', 'NAND2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n_or, n_nand) |
|
|
|
|
elif n.kind.startswith('OA22X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n_or1 = add_and_connect(circuit, name+'~or1', 'OR2', ins[2], ins[3], None) |
|
|
|
|
n_and = add_and_connect(circuit, name+'~and', 'AND2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n_or0, n_and) |
|
|
|
|
Line(circuit, n_or1, n_and) |
|
|
|
|
elif n.kind.startswith('OAI22X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n_or1 = add_and_connect(circuit, name+'~or1', 'OR2', ins[2], ins[3], None) |
|
|
|
|
n_nand = add_and_connect(circuit, name+'~nand', 'NAND2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n_or0, n_nand) |
|
|
|
|
Line(circuit, n_or1, n_nand) |
|
|
|
|
elif n.kind.startswith('AO22X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n_and1 = add_and_connect(circuit, name+'~and1', 'AND2', ins[2], ins[3], None) |
|
|
|
|
n_or = add_and_connect(circuit, name+'~or', 'OR2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n_and0, n_or) |
|
|
|
|
Line(circuit, n_and1, n_or) |
|
|
|
|
elif n.kind.startswith('AOI22X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n_and1 = add_and_connect(circuit, name+'~and1', 'AND2', ins[2], ins[3], None) |
|
|
|
|
n_nor = add_and_connect(circuit, name+'~nor', 'NOR2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n_and0, n_nor) |
|
|
|
|
Line(circuit, n_and1, n_nor) |
|
|
|
|
elif n.kind.startswith('AO221X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n_and1 = add_and_connect(circuit, name+'~and1', 'AND2', ins[2], ins[3], None) |
|
|
|
|
n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', None, None, None) |
|
|
|
|
n_or1 = add_and_connect(circuit, name+'~or1', 'OR2', None, ins[4], outs[0]) |
|
|
|
|
Line(circuit, n_and0, n_or0) |
|
|
|
|
Line(circuit, n_and1, n_or0) |
|
|
|
|
Line(circuit, n_or0, n_or1) |
|
|
|
|
elif n.kind.startswith('AOI221X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n_and1 = add_and_connect(circuit, name+'~and1', 'AND2', ins[2], ins[3], None) |
|
|
|
|
n_or = add_and_connect(circuit, name+'~or', 'OR2', None, None, None) |
|
|
|
|
n_nor = add_and_connect(circuit, name+'~nor', 'NOR2', None, ins[4], outs[0]) |
|
|
|
|
Line(circuit, n_and0, n_or) |
|
|
|
|
Line(circuit, n_and1, n_or) |
|
|
|
|
Line(circuit, n_or, n_nor) |
|
|
|
|
elif n.kind.startswith('OA221X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n_or1 = add_and_connect(circuit, name+'~or1', 'OR2', ins[2], ins[3], None) |
|
|
|
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', None, None, None) |
|
|
|
|
n_and1 = add_and_connect(circuit, name+'~and1', 'AND2', None, ins[4], outs[0]) |
|
|
|
|
Line(circuit, n_or0, n_and0) |
|
|
|
|
Line(circuit, n_or1, n_and0) |
|
|
|
|
Line(circuit, n_and0, n_and1) |
|
|
|
|
elif n.kind.startswith('OAI221X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n_or1 = add_and_connect(circuit, name+'~or1', 'OR2', ins[2], ins[3], None) |
|
|
|
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', None, None, None) |
|
|
|
|
n_nand1 = add_and_connect(circuit, name+'~nand1', 'NAND2', None, ins[4], outs[0]) |
|
|
|
|
Line(circuit, n_or0, n_and0) |
|
|
|
|
Line(circuit, n_or1, n_and0) |
|
|
|
|
Line(circuit, n_and0, n_nand1) |
|
|
|
|
elif n.kind.startswith('AO222X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n_and1 = add_and_connect(circuit, name+'~and1', 'AND2', ins[2], ins[3], None) |
|
|
|
|
n_and2 = add_and_connect(circuit, name+'~and2', 'AND2', ins[4], ins[5], None) |
|
|
|
|
n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', None, None, None) |
|
|
|
|
n_or1 = add_and_connect(circuit, name+'~or1', 'OR2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n_and0, n_or0) |
|
|
|
|
Line(circuit, n_and1, n_or0) |
|
|
|
|
Line(circuit, n_and2, n_or1) |
|
|
|
|
Line(circuit, n_or0, n_or1) |
|
|
|
|
elif n.kind.startswith('AOI222X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n_and1 = add_and_connect(circuit, name+'~and1', 'AND2', ins[2], ins[3], None) |
|
|
|
|
n_and2 = add_and_connect(circuit, name+'~and2', 'AND2', ins[4], ins[5], None) |
|
|
|
|
n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', None, None, None) |
|
|
|
|
n_nor1 = add_and_connect(circuit, name+'~nor1', 'NOR2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n_and0, n_or0) |
|
|
|
|
Line(circuit, n_and1, n_or0) |
|
|
|
|
Line(circuit, n_and2, n_nor1) |
|
|
|
|
Line(circuit, n_or0, n_nor1) |
|
|
|
|
elif n.kind.startswith('OA222X'): |
|
|
|
|
n.remove() |
|
|
|
|
n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n_or1 = add_and_connect(circuit, name+'~or1', 'OR2', ins[2], ins[3], None) |
|
|
|
|
n_or2 = add_and_connect(circuit, name+'~or2', 'OR2', ins[4], ins[5], None) |
|
|
|
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', None, None, None) |
|
|
|
|
n_and1 = add_and_connect(circuit, name+'~and1', 'AND2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n_or0, n_and0) |
|
|
|
|
Line(circuit, n_or1, n_and0) |
|
|
|
|
Line(circuit, n_or2, n_and1) |
|
|
|
|
Line(circuit, n_and0, n_and1) |
|
|
|
|
elif n.kind.startswith('OAI222X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~or1', 'OR2', ins[2], ins[3], None) |
|
|
|
|
n2 = add_and_connect(circuit, name+'~or2', 'OR2', ins[4], ins[5], None) |
|
|
|
|
n3 = add_and_connect(circuit, name+'~and0', 'AND2', None, None, None) |
|
|
|
|
n4 = add_and_connect(circuit, name+'~nand1', 'NAND2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n0, n3) |
|
|
|
|
Line(circuit, n1, n3) |
|
|
|
|
Line(circuit, n2, n4) |
|
|
|
|
Line(circuit, n3, n4) |
|
|
|
|
elif n.kind.startswith('AND3X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~and1', 'AND2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n0, n1) |
|
|
|
|
elif n.kind.startswith('OR3X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~or1', 'OR2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n0, n1) |
|
|
|
|
elif n.kind.startswith('XOR3X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~xor0', 'XOR2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~xor1', 'XOR2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n0, n1) |
|
|
|
|
elif n.kind.startswith('NAND3X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~and', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~nand', 'NAND2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n0, n1) |
|
|
|
|
elif n.kind.startswith('NOR3X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~or', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~nor', 'NOR2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n0, n1) |
|
|
|
|
elif n.kind.startswith('XNOR3X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~xor', 'XOR2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~xnor', 'XNOR2', None, ins[2], outs[0]) |
|
|
|
|
Line(circuit, n0, n1) |
|
|
|
|
elif n.kind.startswith('AND4X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~and1', 'AND2', ins[2], ins[3], None) |
|
|
|
|
n2 = add_and_connect(circuit, name+'~and2', 'AND2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n0, n2) |
|
|
|
|
Line(circuit, n1, n2) |
|
|
|
|
elif n.kind.startswith('OR4X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~or1', 'OR2', ins[2], ins[3], None) |
|
|
|
|
n2 = add_and_connect(circuit, name+'~or2', 'OR2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n0, n2) |
|
|
|
|
Line(circuit, n1, n2) |
|
|
|
|
elif n.kind.startswith('NAND4X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~and1', 'AND2', ins[2], ins[3], None) |
|
|
|
|
n2 = add_and_connect(circuit, name+'~nand2', 'NAND2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n0, n2) |
|
|
|
|
Line(circuit, n1, n2) |
|
|
|
|
elif n.kind.startswith('NOR4X'): |
|
|
|
|
n.remove() |
|
|
|
|
n0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) |
|
|
|
|
n1 = add_and_connect(circuit, name+'~or1', 'OR2', ins[2], ins[3], None) |
|
|
|
|
n2 = add_and_connect(circuit, name+'~nor2', 'NOR2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n0, n2) |
|
|
|
|
Line(circuit, n1, n2) |
|
|
|
|
elif n.kind.startswith('FADDX'): |
|
|
|
|
n.remove() |
|
|
|
|
# forks for fan-outs |
|
|
|
|
f_a = add_and_connect(circuit, name + '~fork0', '__fork__', ins[0]) |
|
|
|
|
f_b = add_and_connect(circuit, name + '~fork1', '__fork__', ins[1]) |
|
|
|
|
f_ci = add_and_connect(circuit, name + '~fork2', '__fork__', ins[2]) |
|
|
|
|
f_ab = Node(circuit, name + '~fork3') |
|
|
|
|
# sum-block |
|
|
|
|
n_xor0 = Node(circuit, name + '~xor0', 'XOR2') |
|
|
|
|
Line(circuit, f_a, n_xor0) |
|
|
|
|
Line(circuit, f_b, n_xor0) |
|
|
|
|
Line(circuit, n_xor0, f_ab) |
|
|
|
|
if len(outs) > 0 and outs[0] is not None: |
|
|
|
|
n_xor1 = add_and_connect(circuit, name + '~xor1', 'XOR2', None, None, outs[0]) |
|
|
|
|
Line(circuit, f_ab, n_xor1) |
|
|
|
|
Line(circuit, f_ci, n_xor1) |
|
|
|
|
# carry-block |
|
|
|
|
if len(outs) > 1 and outs[1] is not None: |
|
|
|
|
n_and0 = Node(circuit, name + '~and0', 'AND2') |
|
|
|
|
Line(circuit, f_ab, n_and0) |
|
|
|
|
Line(circuit, f_ci, n_and0) |
|
|
|
|
n_and1 = Node(circuit, name + '~and1', 'AND2') |
|
|
|
|
Line(circuit, f_a, n_and1) |
|
|
|
|
Line(circuit, f_b, n_and1) |
|
|
|
|
n_or = add_and_connect(circuit, name + '~or0', 'OR2', None, None, outs[1]) |
|
|
|
|
Line(circuit, n_and0, n_or) |
|
|
|
|
Line(circuit, n_and1, n_or) |
|
|
|
|
elif n.kind.startswith('HADDX'): |
|
|
|
|
n.remove() |
|
|
|
|
# forks for fan-outs |
|
|
|
|
f_a = add_and_connect(circuit, name + '~fork0', '__fork__', ins[0]) |
|
|
|
|
f_b = add_and_connect(circuit, name + '~fork1', '__fork__', ins[1]) |
|
|
|
|
n_xor0 = add_and_connect(circuit, name + '~xor0', 'XOR2', None, None, outs[1]) |
|
|
|
|
Line(circuit, f_a, n_xor0) |
|
|
|
|
Line(circuit, f_b, n_xor0) |
|
|
|
|
n_and0 = add_and_connect(circuit, name + '~and0', 'AND2', None, None, outs[0]) |
|
|
|
|
Line(circuit, f_a, n_and0) |
|
|
|
|
Line(circuit, f_b, n_and0) |
|
|
|
|
elif n.kind.startswith('MUX21X'): |
|
|
|
|
n.remove() |
|
|
|
|
f_s = add_and_connect(circuit, name + '~fork0', '__fork__', ins[2]) |
|
|
|
|
n_not = Node(circuit, name + '~not', 'INV') |
|
|
|
|
Line(circuit, f_s, n_not) |
|
|
|
|
n_and0 = add_and_connect(circuit, name + '~and0', 'AND2', ins[0]) |
|
|
|
|
n_and1 = add_and_connect(circuit, name + '~and1', 'AND2', ins[1]) |
|
|
|
|
n_or0 = add_and_connect(circuit, name + '~or0', 'OR2', None, None, outs[0]) |
|
|
|
|
Line(circuit, n_not, n_and0) |
|
|
|
|
Line(circuit, f_s, n_and1) |
|
|
|
|
Line(circuit, n_and0, n_or0) |
|
|
|
|
Line(circuit, n_and1, n_or0) |
|
|
|
|
elif n.kind.startswith('DFFSSR'): |
|
|
|
|
n.kind = 'DFFX1' |
|
|
|
|
n_and0 = add_and_connect(circuit, name + '~and0', 'AND2', ins[0], ins[2], None) |
|
|
|
|
Line(circuit, n_and0, (n, 0)) |
|
|
|
|