Browse Source

fixes for IWLS benchmark netlists

devel
Stefan Holst 4 years ago
parent
commit
8434f5e694
  1. 2
      src/kyupy/techlib.py
  2. 71
      src/kyupy/verilog.py

2
src/kyupy/techlib.py

@ -35,6 +35,8 @@ class TechLib:
for prefix, pins, index in [('HADD', ('B0', 'SO'), 1), for prefix, pins, index in [('HADD', ('B0', 'SO'), 1),
('MUX21', ('S',), 2), ('MUX21', ('S',), 2),
('MX2', ('S0',), 2), ('MX2', ('S0',), 2),
('TBUF', ('OE',), 1),
('TINV', ('OE',), 1),
('DFF', ('QN',), 1), ('DFF', ('QN',), 1),
('DFF', ('D',), 0), ('DFF', ('D',), 0),
('SDFF', ('D',), 0), ('SDFF', ('D',), 0),

71
src/kyupy/verilog.py

@ -8,7 +8,7 @@ from collections import namedtuple
from lark import Lark, Transformer from lark import Lark, Transformer
from . import readtext from . import log, readtext
from .circuit import Circuit, Node, Line from .circuit import Circuit, Node, Line
from .techlib import TechLib from .techlib import TechLib
@ -17,27 +17,21 @@ Instantiation = namedtuple('Instantiation', ['type', 'name', 'pins'])
class SignalDeclaration: class SignalDeclaration:
def __init__(self, kind, tokens): def __init__(self, kind, name, rnge=None):
self.left = None self.left = None
self.right = None self.right = None
self.kind = kind self.kind = kind
if len(tokens.children) == 1: self.basename = name
self.basename = tokens.children[0] self.rnge = rnge
else:
self.basename = tokens.children[2]
self.left = int(tokens.children[0].value)
self.right = int(tokens.children[1].value)
@property @property
def names(self): def names(self):
if self.left is None: if self.rnge is None:
return [self.basename] return [self.basename]
if self.left <= self.right: return [f'{self.basename}[{i}]' for i in self.rnge]
return [f'{self.basename}[{i}]' for i in range(self.left, self.right + 1)]
return [f'{self.basename}[{i}]' for i in range(self.left, self.right - 1, -1)]
def __repr__(self): def __repr__(self):
return f"{self.kind}:{self.basename}[{self.left}:{self.right}]" return f"{self.kind}:{self.basename}[{self.rnge}]"
class VerilogTransformer(Transformer): class VerilogTransformer(Transformer):
@ -60,22 +54,24 @@ class VerilogTransformer(Transformer):
dict((pin.children[0], dict((pin.children[0],
pin.children[1]) for pin in args[2:] if len(pin.children) > 1)) pin.children[1]) for pin in args[2:] if len(pin.children) > 1))
def input(self, args): def range(self, args):
for sd in [SignalDeclaration('input', signal) for signal in args]: left = int(args[0].value)
self._signal_declarations[sd.basename] = sd right = int(args[1].value)
return range(left, right+1) if left <= right else range(left, right-1, -1)
def inout(self, args):
for sd in [SignalDeclaration('input', signal) for signal in args]: # just treat as input def declaration(self, kind, args):
rnge = None
if isinstance(args[0], range):
rnge = args[0]
args = args[1:]
for sd in [SignalDeclaration(kind, signal, rnge) for signal in args]:
if kind != 'wire' or sd.basename not in self._signal_declarations:
self._signal_declarations[sd.basename] = sd self._signal_declarations[sd.basename] = sd
def output(self, args): def input(self, args): self.declaration("input", args)
for sd in [SignalDeclaration('output', signal) for signal in args]: def output(self, args): self.declaration("output", args)
self._signal_declarations[sd.basename] = sd def inout(self, args): self.declaration("input", args) # just treat as input
def wire(self, args): self.declaration("wire", args)
def wire(self, args):
for sd in [SignalDeclaration('wire', signal) for signal in args]:
if sd.basename not in self._signal_declarations:
self._signal_declarations[sd.basename] = sd
def module(self, args): def module(self, args):
c = Circuit(args[0]) c = Circuit(args[0])
@ -125,6 +121,9 @@ class VerilogTransformer(Transformer):
const_count += 1 const_count += 1
s = cname s = cname
Line(c, cnode, Node(c, s)) Line(c, cnode, Node(c, s))
if s not in c.forks:
log.warn(f'Signal not driven: {s}')
Node(c, s) # generate fork here
fork = c.forks[s] fork = c.forks[s]
if self.branchforks: if self.branchforks:
branchfork = Node(c, fork.name + "~" + n.name + "/" + p) branchfork = Node(c, fork.name + "~" + n.name + "/" + p)
@ -134,6 +133,9 @@ class VerilogTransformer(Transformer):
for sd in self._signal_declarations.values(): for sd in self._signal_declarations.values():
if sd.kind == 'output': if sd.kind == 'output':
for name in sd.names: for name in sd.names:
if name not in c.forks:
log.warn(f'Output not driven: {name}')
else:
Line(c, c.forks[name], c.cells[name]) Line(c, c.forks[name], c.cells[name])
return c return c
@ -144,18 +146,19 @@ class VerilogTransformer(Transformer):
GRAMMAR = """ GRAMMAR = """
start: (module)* start: (module)*
module: "module" name parameters ";" (_statement)* "endmodule" module: "module" name parameters ";" (_statement)* "endmodule"
parameters: "(" [ name ( "," name )* ] ")" parameters: "(" [ _namelist ] ")"
_statement: input | output | inout | tri | wire | assign | instantiation _statement: input | output | inout | tri | wire | assign | instantiation
input: "input" signal ( "," signal )* ";" input: "input" range? _namelist ";"
output: "output" signal ( "," signal )* ";" output: "output" range? _namelist ";"
inout: "inout" signal ( "," signal )* ";" inout: "inout" range? _namelist ";"
tri: "tri" name ";" tri: "tri" range? _namelist ";"
wire: "wire" signal ( "," signal )* ";" wire: "wire" range? _namelist ";"
assign: "assign" name "=" name ";" assign: "assign" name "=" name ";"
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";" instantiation: name name "(" [ pin ( "," pin )* ] ")" ";"
pin: "." name "(" name? ")" pin: "." name "(" name? ")"
signal: ( name | "[" /[0-9]+/ ":" /[0-9]+/ "]" name ) range: "[" /[0-9]+/ ":" /[0-9]+/ "]"
_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](\\[[0-9]+\\])?/i | /1'b0/i | /1'b1/i )
COMMENT: "//" /[^\\n]*/ COMMENT: "//" /[^\\n]*/
%ignore ( /\\r?\\n/ | COMMENT )+ %ignore ( /\\r?\\n/ | COMMENT )+

Loading…
Cancel
Save