|
|
@ -37,7 +37,6 @@ class SignalDeclaration: |
|
|
|
class VerilogTransformer(Transformer): |
|
|
|
class VerilogTransformer(Transformer): |
|
|
|
def __init__(self, branchforks=False, tlib=TechLib()): |
|
|
|
def __init__(self, branchforks=False, tlib=TechLib()): |
|
|
|
super().__init__() |
|
|
|
super().__init__() |
|
|
|
self._signal_declarations = {} |
|
|
|
|
|
|
|
self.branchforks = branchforks |
|
|
|
self.branchforks = branchforks |
|
|
|
self.tlib = tlib |
|
|
|
self.tlib = tlib |
|
|
|
|
|
|
|
|
|
|
@ -46,14 +45,20 @@ class VerilogTransformer(Transformer): |
|
|
|
s = args[0].value |
|
|
|
s = args[0].value |
|
|
|
return s[1:-1] if s[0] == '\\' else s |
|
|
|
return s[1:-1] if s[0] == '\\' else s |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
|
|
|
def namedpin(args): |
|
|
|
|
|
|
|
return tuple(args) if len(args) > 1 else (args[0], None) |
|
|
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
@staticmethod |
|
|
|
def instantiation(args): |
|
|
|
def instantiation(args): |
|
|
|
pinmap = {} |
|
|
|
pinmap = {} |
|
|
|
for idx, pin in enumerate(args[2:]): |
|
|
|
for idx, pin in enumerate(args[2:]): |
|
|
|
if len(pin.children) > 1: |
|
|
|
p = pin.children[0] |
|
|
|
pinmap[pin.children[0]] = pin.children[1] |
|
|
|
if isinstance(p, tuple): # named pin |
|
|
|
else: |
|
|
|
if p[1] is not None: |
|
|
|
pinmap[idx] = pin.children[0] |
|
|
|
pinmap[p[0]] = p[1] |
|
|
|
|
|
|
|
else: # unnamed pin |
|
|
|
|
|
|
|
pinmap[idx] = p |
|
|
|
return Instantiation(args[0], args[1], pinmap) |
|
|
|
return Instantiation(args[0], args[1], pinmap) |
|
|
|
|
|
|
|
|
|
|
|
def range(self, args): |
|
|
|
def range(self, args): |
|
|
@ -104,14 +109,15 @@ class VerilogTransformer(Transformer): |
|
|
|
positions = {} |
|
|
|
positions = {} |
|
|
|
pos = 0 |
|
|
|
pos = 0 |
|
|
|
const_count = 0 |
|
|
|
const_count = 0 |
|
|
|
self._signal_declarations = {} |
|
|
|
sig_decls = {} |
|
|
|
for decls in args[2:]: # pass 0: collect signal declarations |
|
|
|
for decls in args[2:]: # pass 0: collect signal declarations |
|
|
|
if isinstance(decls, list): |
|
|
|
if isinstance(decls, list): |
|
|
|
if len(decls) > 0 and isinstance(decls[0], SignalDeclaration): |
|
|
|
if len(decls) > 0 and isinstance(decls[0], SignalDeclaration): |
|
|
|
for decl in decls: |
|
|
|
for decl in decls: |
|
|
|
self._signal_declarations[decl.basename] = decl |
|
|
|
if decl.basename not in sig_decls or sig_decls[decl.basename].kind == 'wire': |
|
|
|
|
|
|
|
sig_decls[decl.basename] = decl |
|
|
|
for intf_sig in args[1].children: |
|
|
|
for intf_sig in args[1].children: |
|
|
|
for name in self._signal_declarations[intf_sig].names: |
|
|
|
for name in sig_decls[intf_sig].names: |
|
|
|
positions[name] = pos |
|
|
|
positions[name] = pos |
|
|
|
pos += 1 |
|
|
|
pos += 1 |
|
|
|
assignments = [] |
|
|
|
assignments = [] |
|
|
@ -123,7 +129,7 @@ class VerilogTransformer(Transformer): |
|
|
|
Line(c, (n, self.tlib.pin_index(stmt.type, p)), Node(c, s)) |
|
|
|
Line(c, (n, self.tlib.pin_index(stmt.type, p)), Node(c, s)) |
|
|
|
elif hasattr(stmt, 'data') and stmt.data == 'assign': |
|
|
|
elif hasattr(stmt, 'data') and stmt.data == 'assign': |
|
|
|
assignments.append((stmt.children[0], stmt.children[1])) |
|
|
|
assignments.append((stmt.children[0], stmt.children[1])) |
|
|
|
for sd in self._signal_declarations.values(): |
|
|
|
for sd in sig_decls.values(): |
|
|
|
if sd.kind == 'output' or sd.kind == 'input': |
|
|
|
if sd.kind == 'output' or sd.kind == 'input': |
|
|
|
for name in sd.names: |
|
|
|
for name in sd.names: |
|
|
|
n = Node(c, name, kind=sd.kind) |
|
|
|
n = Node(c, name, kind=sd.kind) |
|
|
@ -135,15 +141,15 @@ class VerilogTransformer(Transformer): |
|
|
|
target_sigs = [] |
|
|
|
target_sigs = [] |
|
|
|
if not isinstance(target, list): target = [target] |
|
|
|
if not isinstance(target, list): target = [target] |
|
|
|
for s in target: |
|
|
|
for s in target: |
|
|
|
if s in self._signal_declarations: |
|
|
|
if s in sig_decls: |
|
|
|
target_sigs += self._signal_declarations[s].names |
|
|
|
target_sigs += sig_decls[s].names |
|
|
|
else: |
|
|
|
else: |
|
|
|
target_sigs.append(s) |
|
|
|
target_sigs.append(s) |
|
|
|
source_sigs = [] |
|
|
|
source_sigs = [] |
|
|
|
if not isinstance(source, list): source = [source] |
|
|
|
if not isinstance(source, list): source = [source] |
|
|
|
for s in source: |
|
|
|
for s in source: |
|
|
|
if s in self._signal_declarations: |
|
|
|
if s in sig_decls: |
|
|
|
source_sigs += self._signal_declarations[s].names |
|
|
|
source_sigs += sig_decls[s].names |
|
|
|
else: |
|
|
|
else: |
|
|
|
source_sigs.append(s) |
|
|
|
source_sigs.append(s) |
|
|
|
for t, s in zip(target_sigs, source_sigs): |
|
|
|
for t, s in zip(target_sigs, source_sigs): |
|
|
@ -177,7 +183,7 @@ class VerilogTransformer(Transformer): |
|
|
|
Line(c, fork, branchfork) |
|
|
|
Line(c, fork, branchfork) |
|
|
|
fork = branchfork |
|
|
|
fork = branchfork |
|
|
|
Line(c, fork, (n, self.tlib.pin_index(stmt.type, p))) |
|
|
|
Line(c, fork, (n, self.tlib.pin_index(stmt.type, p))) |
|
|
|
for sd in self._signal_declarations.values(): |
|
|
|
for sd in sig_decls.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: |
|
|
|
if name not in c.forks: |
|
|
@ -202,7 +208,8 @@ GRAMMAR = r""" |
|
|
|
wire: "wire" range? _namelist ";" |
|
|
|
wire: "wire" range? _namelist ";" |
|
|
|
assign: "assign" sigsel "=" sigsel ";" |
|
|
|
assign: "assign" sigsel "=" sigsel ";" |
|
|
|
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";" |
|
|
|
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";" |
|
|
|
pin: ("." name "(" sigsel? ")" ) | sigsel |
|
|
|
pin: namedpin | sigsel |
|
|
|
|
|
|
|
namedpin: "." name "(" sigsel? ")" |
|
|
|
range: "[" /[0-9]+/ (":" /[0-9]+/)? "]" |
|
|
|
range: "[" /[0-9]+/ (":" /[0-9]+/)? "]" |
|
|
|
sigsel: name range? | concat |
|
|
|
sigsel: name range? | concat |
|
|
|
concat: "{" sigsel ( "," sigsel )* "}" |
|
|
|
concat: "{" sigsel ( "," sigsel )* "}" |
|
|
|