support concat, bus select, ISOL cells
This commit is contained in:
1 parent
f61e2b42e8
commit
f8bf579be2
3 files changed
+82
-19
No files matched your search
@@ -47,7 +47,9 @@ class TechLib:
|
|||||||
('SDFF', ('QN',), 1),
|
('SDFF', ('QN',), 1),
|
||||||
('SDFF', ('CLK',), 3),
|
('SDFF', ('CLK',), 3),
|
||||||
('SDFF', ('RSTB', 'RN'), 4),
|
('SDFF', ('RSTB', 'RN'), 4),
|
||||||
('SDFF', ('SETB',), 5)]:
|
('SDFF', ('SETB',), 5),
|
||||||
|
('ISOL', ('ISO',), 0),
|
||||||
|
('ISOL', ('D',), 1)]:
|
||||||
if kind.startswith(prefix) and pin in pins: return index
|
if kind.startswith(prefix) and pin in pins: return index
|
||||||
for index, pins in enumerate([('A1', 'IN1', 'A', 'S', 'INP', 'I', 'Q', 'QN', 'Y', 'Z', 'ZN'),
|
for index, pins in enumerate([('A1', 'IN1', 'A', 'S', 'INP', 'I', 'Q', 'QN', 'Y', 'Z', 'ZN'),
|
||||||
('A2', 'IN2', 'B', 'CK', 'CLK', 'CO', 'SE'),
|
('A2', 'IN2', 'B', 'CK', 'CLK', 'CO', 'SE'),
|
||||||
|
|||||||
+40
-16
@@ -44,9 +44,7 @@ class VerilogTransformer(Transformer):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def name(args):
|
def name(args):
|
||||||
s = args[0].value
|
s = args[0].value
|
||||||
if s[0] == '\\':
|
return s[1:-1] if s[0] == '\\' else s
|
||||||
s = s[1:].replace(' ','')
|
|
||||||
return s
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def instantiation(args):
|
def instantiation(args):
|
||||||
@@ -56,9 +54,25 @@ class VerilogTransformer(Transformer):
|
|||||||
|
|
||||||
def range(self, args):
|
def range(self, args):
|
||||||
left = int(args[0].value)
|
left = int(args[0].value)
|
||||||
right = int(args[1].value)
|
right = int(args[1].value) if len(args) > 1 else left
|
||||||
return range(left, right+1) if left <= right else range(left, right-1, -1)
|
return range(left, right+1) if left <= right else range(left, right-1, -1)
|
||||||
|
|
||||||
|
def sigsel(self, args):
|
||||||
|
if len(args) > 1 and isinstance(args[1], range):
|
||||||
|
l = [f'{args[0]}[{i}]' for i in args[1]]
|
||||||
|
return l if len(l) > 1 else l[0]
|
||||||
|
else:
|
||||||
|
return args[0]
|
||||||
|
|
||||||
|
def concat(self, args):
|
||||||
|
sigs = []
|
||||||
|
for a in args:
|
||||||
|
if isinstance(a, list):
|
||||||
|
sigs += a
|
||||||
|
else:
|
||||||
|
sigs.append(a)
|
||||||
|
return sigs
|
||||||
|
|
||||||
def declaration(self, kind, args):
|
def declaration(self, kind, args):
|
||||||
rnge = None
|
rnge = None
|
||||||
if isinstance(args[0], range):
|
if isinstance(args[0], range):
|
||||||
@@ -110,12 +124,23 @@ class VerilogTransformer(Transformer):
|
|||||||
cnode = Node(c, f'__const{s2[3]}_{const_count}__', f'__const{s2[3]}__')
|
cnode = Node(c, f'__const{s2[3]}_{const_count}__', f'__const{s2[3]}__')
|
||||||
const_count += 1
|
const_count += 1
|
||||||
Line(c, cnode, Node(c, s1))
|
Line(c, cnode, Node(c, s1))
|
||||||
for s1, s2 in assignments: # pass 1.5: process signal assignments
|
for target, source in assignments: # pass 1.5: process signal assignments
|
||||||
if isinstance(s2, Tree) and s2.data == 'concatenation':
|
target_sigs = []
|
||||||
for target, source in zip(self._signal_declarations[s1].names, s2.children):
|
if not isinstance(target, list): target = [target]
|
||||||
assign_wire(target, source)
|
for s in target:
|
||||||
else:
|
if s in self._signal_declarations:
|
||||||
assign_wire(s1, s2)
|
target_sigs += self._signal_declarations[s].names
|
||||||
|
else:
|
||||||
|
target_sigs.append(s)
|
||||||
|
source_sigs = []
|
||||||
|
if not isinstance(source, list): source = [source]
|
||||||
|
for s in source:
|
||||||
|
if s in self._signal_declarations:
|
||||||
|
source_sigs += self._signal_declarations[s].names
|
||||||
|
else:
|
||||||
|
source_sigs.append(s)
|
||||||
|
for t, s in zip(target_sigs, source_sigs):
|
||||||
|
assign_wire(t, s)
|
||||||
for stmt in args[2:]: # pass 2: connect signals to readers
|
for stmt in args[2:]: # pass 2: connect signals to readers
|
||||||
if isinstance(stmt, Instantiation):
|
if isinstance(stmt, Instantiation):
|
||||||
for p, s in stmt.pins.items():
|
for p, s in stmt.pins.items():
|
||||||
@@ -159,15 +184,14 @@ GRAMMAR = r"""
|
|||||||
inout: "inout" range? _namelist ";"
|
inout: "inout" range? _namelist ";"
|
||||||
tri: "tri" range? _namelist ";"
|
tri: "tri" range? _namelist ";"
|
||||||
wire: "wire" range? _namelist ";"
|
wire: "wire" range? _namelist ";"
|
||||||
assign: "assign" lvalue "=" _expression ";"
|
assign: "assign" sigsel "=" sigsel ";"
|
||||||
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";"
|
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";"
|
||||||
pin: "." name "(" name? ")"
|
pin: "." name "(" sigsel? ")"
|
||||||
range: "[" /[0-9]+/ (":" /[0-9]+/)? "]"
|
range: "[" /[0-9]+/ (":" /[0-9]+/)? "]"
|
||||||
?lvalue: name range?
|
sigsel: name range? | concat
|
||||||
_expression: name | concatenation
|
concat: "{" sigsel ( "," sigsel )* "}"
|
||||||
concatenation: "{" _namelist "}"
|
|
||||||
_namelist: name ( "," name )*
|
_namelist: name ( "," 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]/i | /1'b0/i | /1'b1/i )
|
||||||
%import common.NEWLINE
|
%import common.NEWLINE
|
||||||
COMMENT: /\/\*(\*(?!\/)|[^*])*\*\// | /\(\*(\*(?!\))|[^*])*\*\)/ | "//" /(.)*/ NEWLINE
|
COMMENT: /\/\*(\*(?!\/)|[^*])*\*\// | /\(\*(\*(?!\))|[^*])*\*\)/ | "//" /(.)*/ NEWLINE
|
||||||
%ignore ( /\r?\n/ | COMMENT )+
|
%ignore ( /\r?\n/ | COMMENT )+
|
||||||
|
|||||||
+39
-2
@@ -3,6 +3,43 @@ from kyupy import verilog
|
|||||||
|
|
||||||
def test_b01(mydir):
|
def test_b01(mydir):
|
||||||
with open(mydir / 'b01.v', 'r') as f:
|
with open(mydir / 'b01.v', 'r') as f:
|
||||||
modules = verilog.parse(f.read())
|
c = verilog.parse(f.read())
|
||||||
assert modules is not None
|
assert c is not None
|
||||||
assert verilog.load(mydir / 'b01.v') is not None
|
assert verilog.load(mydir / 'b01.v') is not None
|
||||||
|
|
||||||
|
assert len(c.nodes) == 139
|
||||||
|
assert len(c.lines) == 203
|
||||||
|
stats = c.stats
|
||||||
|
assert stats['input'] == 6
|
||||||
|
assert stats['output'] == 3
|
||||||
|
assert stats['__seq__'] == 5
|
||||||
|
|
||||||
|
|
||||||
|
def test_b15(mydir):
|
||||||
|
c = verilog.load(mydir / 'b15_4ig.v.gz')
|
||||||
|
assert len(c.nodes) == 12067
|
||||||
|
assert len(c.lines) == 20731
|
||||||
|
stats = c.stats
|
||||||
|
assert stats['input'] == 40
|
||||||
|
assert stats['output'] == 71
|
||||||
|
assert stats['__seq__'] == 417
|
||||||
|
|
||||||
|
|
||||||
|
def test_gates(mydir):
|
||||||
|
c = verilog.load(mydir / 'gates.v')
|
||||||
|
assert len(c.nodes) == 10
|
||||||
|
assert len(c.lines) == 10
|
||||||
|
stats = c.stats
|
||||||
|
assert stats['input'] == 2
|
||||||
|
assert stats['output'] == 2
|
||||||
|
assert stats['__seq__'] == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_halton2(mydir):
|
||||||
|
c = verilog.load(mydir / 'rng_haltonBase2.synth_yosys.v')
|
||||||
|
assert len(c.nodes) == 146
|
||||||
|
assert len(c.lines) == 210
|
||||||
|
stats = c.stats
|
||||||
|
assert stats['input'] == 2
|
||||||
|
assert stats['output'] == 12
|
||||||
|
assert stats['__seq__'] == 12
|
||||||
Reference in new issue
Block a user