support more SAED cells, improve verilog parsing, fix inspection warnings
This commit is contained in:
1 parent
0c5a7f56e1
commit
3ad95153ab
4 files changed
+133
-15
No files matched your search
@@ -45,6 +45,7 @@ class MockCuda:
|
|||||||
self.y = 0
|
self.y = 0
|
||||||
|
|
||||||
def jit(self, device=False):
|
def jit(self, device=False):
|
||||||
|
_ = device # silence "not used" warning
|
||||||
outer = self
|
outer = self
|
||||||
|
|
||||||
def make_launcher(func):
|
def make_launcher(func):
|
||||||
@@ -84,6 +85,7 @@ class MockCuda:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def grid(self, dims):
|
def grid(self, dims):
|
||||||
|
_ = dims # silence "not used" warning
|
||||||
return self.x, self.y
|
return self.x, self.y
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+111
-7
@@ -2,10 +2,14 @@ from kyupy.circuit import Node, Line
|
|||||||
|
|
||||||
|
|
||||||
def pin_index(cell_type, pin):
|
def pin_index(cell_type, pin):
|
||||||
|
if cell_type.startswith('HADD') and pin == 'B0': return 1
|
||||||
|
if cell_type.startswith('HADD') and pin == 'SO': return 1
|
||||||
if cell_type.startswith('MUX21') and pin == 'S': return 2
|
if cell_type.startswith('MUX21') and pin == 'S': return 2
|
||||||
if cell_type.startswith('SDFF') and pin == 'QN': return 1
|
if cell_type.startswith('SDFF') and pin == 'QN': return 1
|
||||||
if cell_type.startswith('DFF') and pin == 'QN': return 1
|
if cell_type.startswith('DFF') and pin == 'QN': return 1
|
||||||
if cell_type.startswith('DFF') and pin == 'CLK': return 1
|
if cell_type.startswith('DFF') and pin == 'CLK': return 1
|
||||||
|
if cell_type.startswith('DFF') and pin == 'RSTB': return 2
|
||||||
|
if cell_type.startswith('DFF') and pin == 'SETB': return 3
|
||||||
if pin in ['A2', 'IN2', 'SE', 'B', 'CO']: return 1
|
if pin in ['A2', 'IN2', 'SE', 'B', 'CO']: return 1
|
||||||
if pin in ['A3', 'IN3', 'SI', 'CI']: return 2
|
if pin in ['A3', 'IN3', 'SI', 'CI']: return 2
|
||||||
if pin == 'A4' or pin == 'IN4' or pin == 'CLK': return 3 # CLK for scan cells SDFF
|
if pin == 'A4' or pin == 'IN4' or pin == 'CLK': return 3 # CLK for scan cells SDFF
|
||||||
@@ -17,7 +21,7 @@ def pin_index(cell_type, pin):
|
|||||||
def pin_is_output(kind, pin):
|
def pin_is_output(kind, pin):
|
||||||
if 'MUX' in kind and pin == 'S':
|
if 'MUX' in kind and pin == 'S':
|
||||||
return False
|
return False
|
||||||
return pin in ['Q', 'QN', 'Z', 'ZN', 'Y', 'CO', 'S']
|
return pin in ['Q', 'QN', 'Z', 'ZN', 'Y', 'CO', 'S', 'SO', 'C1']
|
||||||
|
|
||||||
|
|
||||||
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):
|
||||||
@@ -58,7 +62,7 @@ def split_complex_gates(circuit):
|
|||||||
n_or = add_and_connect(circuit, name+'~or', 'OR2', ins[0], ins[1], None)
|
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])
|
n_and = add_and_connect(circuit, name+'~and', 'AND2', None, ins[2], outs[0])
|
||||||
Line(circuit, n_or, n_and)
|
Line(circuit, n_or, n_and)
|
||||||
elif n.kind.startswith('OAI21'):
|
elif n.kind.startswith('OAI21X'):
|
||||||
n.remove()
|
n.remove()
|
||||||
n_or = add_and_connect(circuit, name+'~or', 'OR2', ins[0], ins[1], None)
|
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])
|
n_nand = add_and_connect(circuit, name+'~nand', 'NAND2', None, ins[2], outs[0])
|
||||||
@@ -70,6 +74,13 @@ def split_complex_gates(circuit):
|
|||||||
n_and = add_and_connect(circuit, name+'~and', 'AND2', None, None, outs[0])
|
n_and = add_and_connect(circuit, name+'~and', 'AND2', None, None, outs[0])
|
||||||
Line(circuit, n_or0, n_and)
|
Line(circuit, n_or0, n_and)
|
||||||
Line(circuit, n_or1, 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'):
|
elif n.kind.startswith('AO22X'):
|
||||||
n.remove()
|
n.remove()
|
||||||
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None)
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None)
|
||||||
@@ -77,6 +88,13 @@ def split_complex_gates(circuit):
|
|||||||
n_or = add_and_connect(circuit, name+'~or', 'OR2', None, None, outs[0])
|
n_or = add_and_connect(circuit, name+'~or', 'OR2', None, None, outs[0])
|
||||||
Line(circuit, n_and0, n_or)
|
Line(circuit, n_and0, n_or)
|
||||||
Line(circuit, n_and1, 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'):
|
elif n.kind.startswith('AO221X'):
|
||||||
n.remove()
|
n.remove()
|
||||||
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None)
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None)
|
||||||
@@ -104,6 +122,15 @@ def split_complex_gates(circuit):
|
|||||||
Line(circuit, n_or0, n_and0)
|
Line(circuit, n_or0, n_and0)
|
||||||
Line(circuit, n_or1, n_and0)
|
Line(circuit, n_or1, n_and0)
|
||||||
Line(circuit, n_and0, n_and1)
|
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'):
|
elif n.kind.startswith('AO222X'):
|
||||||
n.remove()
|
n.remove()
|
||||||
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None)
|
n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None)
|
||||||
@@ -137,11 +164,75 @@ def split_complex_gates(circuit):
|
|||||||
Line(circuit, n_or1, n_and0)
|
Line(circuit, n_or1, n_and0)
|
||||||
Line(circuit, n_or2, n_and1)
|
Line(circuit, n_or2, n_and1)
|
||||||
Line(circuit, n_and0, 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'):
|
elif n.kind.startswith('NOR3X'):
|
||||||
n.remove()
|
n.remove()
|
||||||
n_or = add_and_connect(circuit, name+'~or', 'OR2', ins[0], ins[1], None)
|
n0 = add_and_connect(circuit, name+'~or', 'OR2', ins[0], ins[1], None)
|
||||||
n_nor = add_and_connect(circuit, name+'~nor', 'NOR2', None, ins[2], outs[0])
|
n1 = add_and_connect(circuit, name+'~nor', 'NOR2', None, ins[2], outs[0])
|
||||||
Line(circuit, n_or, n_nor)
|
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'):
|
elif n.kind.startswith('FADDX'):
|
||||||
n.remove()
|
n.remove()
|
||||||
# forks for fan-outs
|
# forks for fan-outs
|
||||||
@@ -169,6 +260,17 @@ def split_complex_gates(circuit):
|
|||||||
n_or = add_and_connect(circuit, name + '~or0', 'OR2', None, None, outs[1])
|
n_or = add_and_connect(circuit, name + '~or0', 'OR2', None, None, outs[1])
|
||||||
Line(circuit, n_and0, n_or)
|
Line(circuit, n_and0, n_or)
|
||||||
Line(circuit, n_and1, 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'):
|
elif n.kind.startswith('MUX21X'):
|
||||||
n.remove()
|
n.remove()
|
||||||
f_s = add_and_connect(circuit, name + '~fork0', '__fork__', ins[2])
|
f_s = add_and_connect(circuit, name + '~fork0', '__fork__', ins[2])
|
||||||
@@ -181,5 +283,7 @@ def split_complex_gates(circuit):
|
|||||||
Line(circuit, f_s, n_and1)
|
Line(circuit, f_s, n_and1)
|
||||||
Line(circuit, n_and0, n_or0)
|
Line(circuit, n_and0, n_or0)
|
||||||
Line(circuit, n_and1, 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))
|
||||||
+1
-1
@@ -170,7 +170,7 @@ class SdfTransformer(Transformer):
|
|||||||
return DelayFile(name, cells)
|
return DelayFile(name, cells)
|
||||||
|
|
||||||
|
|
||||||
def parse(sdf) -> DelayFile:
|
def parse(sdf):
|
||||||
grammar = r"""
|
grammar = r"""
|
||||||
start: "(DELAYFILE" ( "(SDFVERSION" _NOB ")"
|
start: "(DELAYFILE" ( "(SDFVERSION" _NOB ")"
|
||||||
| "(DESIGN" "\"" NAME "\"" ")"
|
| "(DESIGN" "\"" NAME "\"" ")"
|
||||||
|
|||||||
+19
-7
@@ -1,6 +1,8 @@
|
|||||||
from lark import Lark, Transformer
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import gzip
|
import gzip
|
||||||
|
|
||||||
|
from lark import Lark, Transformer
|
||||||
|
|
||||||
from .circuit import Circuit, Node, Line
|
from .circuit import Circuit, Node, Line
|
||||||
from .saed import pin_index, pin_is_output
|
from .saed import pin_index, pin_is_output
|
||||||
|
|
||||||
@@ -110,7 +112,7 @@ class VerilogTransformer(Transformer):
|
|||||||
Line(c, Node(c, const, const), Node(c, s))
|
Line(c, Node(c, const, const), Node(c, s))
|
||||||
fork = c.forks[s]
|
fork = c.forks[s]
|
||||||
if self.branchforks:
|
if self.branchforks:
|
||||||
branchfork = Node(c, fork.name + "~" + n.name)
|
branchfork = Node(c, fork.name + "~" + n.name + "/" + p)
|
||||||
Line(c, fork, branchfork)
|
Line(c, fork, branchfork)
|
||||||
fork = branchfork
|
fork = branchfork
|
||||||
Line(c, fork, (n, pin_index(stmt.type, p)))
|
Line(c, fork, (n, pin_index(stmt.type, p)))
|
||||||
@@ -126,10 +128,9 @@ class VerilogTransformer(Transformer):
|
|||||||
return args[0]
|
return args[0]
|
||||||
else:
|
else:
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
||||||
def parse(verilog, branchforks=False) -> Circuit:
|
|
||||||
grammar = """
|
grammar = """
|
||||||
start: (module)*
|
start: (module)*
|
||||||
module: "module" name parameters ";" (_statement)* "endmodule"
|
module: "module" name parameters ";" (_statement)* "endmodule"
|
||||||
parameters: "(" [ name ( "," name )* ] ")"
|
parameters: "(" [ name ( "," name )* ] ")"
|
||||||
@@ -143,12 +144,23 @@ def parse(verilog, branchforks=False) -> Circuit:
|
|||||||
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";"
|
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";"
|
||||||
pin: "." name "(" name ")"
|
pin: "." name "(" name ")"
|
||||||
signal: ( name | "[" /[0-9]+/ ":" /[0-9]+/ "]" name )
|
signal: ( name | "[" /[0-9]+/ ":" /[0-9]+/ "]" name )
|
||||||
|
|
||||||
name: ( /[a-z_][a-z0-9_\\[\\]]*/i | /\\\\[^\\t \\r\\n]+[\\t \\r\\n](\\[[0-9]+\\])?/i | /1'b0/i | /1'b1/i )
|
name: ( /[a-z_][a-z0-9_\\[\\]]*/i | /\\\\[^\\t \\r\\n]+[\\t \\r\\n](\\[[0-9]+\\])?/i | /1'b0/i | /1'b1/i )
|
||||||
COMMENT: "//" /[^\\n]*/
|
COMMENT: "//" /[^\\n]*/
|
||||||
%ignore ( /\\r?\\n/ | COMMENT )+
|
%ignore ( /\\r?\\n/ | COMMENT )+
|
||||||
%ignore /[\\t \\f]+/
|
%ignore /[\\t \\f]+/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def loads(s, *, branchforks=False):
|
||||||
|
return Lark(grammar, parser="lalr", transformer=VerilogTransformer(branchforks)).parse(s)
|
||||||
|
|
||||||
|
|
||||||
|
def load(fp, *, branchforks=False):
|
||||||
|
return loads(fp.read(), branchforks=branchforks)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(verilog, branchforks=False):
|
||||||
if '\n' not in str(verilog): # One line?: Assuming it is a file name.
|
if '\n' not in str(verilog): # One line?: Assuming it is a file name.
|
||||||
if str(verilog).endswith('.gz'):
|
if str(verilog).endswith('.gz'):
|
||||||
with gzip.open(verilog, 'rt') as f:
|
with gzip.open(verilog, 'rt') as f:
|
||||||
@@ -158,4 +170,4 @@ def parse(verilog, branchforks=False) -> Circuit:
|
|||||||
text = f.read()
|
text = f.read()
|
||||||
else:
|
else:
|
||||||
text = str(verilog)
|
text = str(verilog)
|
||||||
return Lark(grammar, parser="lalr", transformer=VerilogTransformer(branchforks)).parse(text)
|
return loads(text, branchforks=branchforks)
|
||||||
Reference in new issue
Block a user