|
|
|
@ -6,7 +6,7 @@ It supports only a subset of Verilog.
@@ -6,7 +6,7 @@ It supports only a subset of Verilog.
|
|
|
|
|
|
|
|
|
|
from collections import namedtuple |
|
|
|
|
|
|
|
|
|
from lark import Lark, Transformer |
|
|
|
|
from lark import Lark, Transformer, Tree |
|
|
|
|
|
|
|
|
|
from . import log, readtext |
|
|
|
|
from .circuit import Circuit, Node, Line |
|
|
|
@ -45,7 +45,7 @@ class VerilogTransformer(Transformer):
@@ -45,7 +45,7 @@ class VerilogTransformer(Transformer):
|
|
|
|
|
def name(args): |
|
|
|
|
s = args[0].value |
|
|
|
|
if s[0] == '\\': |
|
|
|
|
s = s[1:-1] |
|
|
|
|
s = s[1:].replace(' ','') |
|
|
|
|
return s |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
@ -99,7 +99,7 @@ class VerilogTransformer(Transformer):
@@ -99,7 +99,7 @@ class VerilogTransformer(Transformer):
|
|
|
|
|
c.io_nodes[positions[name]] = n |
|
|
|
|
if sd.kind == 'input': |
|
|
|
|
Line(c, n, Node(c, name)) |
|
|
|
|
for s1, s2 in assignments: # pass 1.5: process signal assignments |
|
|
|
|
def assign_wire(s1, s2): |
|
|
|
|
if s1 in c.forks: |
|
|
|
|
assert s2 not in c.forks, 'assignment between two driven signals' |
|
|
|
|
Line(c, c.forks[s1], Node(c, s2)) |
|
|
|
@ -110,6 +110,12 @@ class VerilogTransformer(Transformer):
@@ -110,6 +110,12 @@ class VerilogTransformer(Transformer):
|
|
|
|
|
cnode = Node(c, f'__const{s2[3]}_{const_count}__', f'__const{s2[3]}__') |
|
|
|
|
const_count += 1 |
|
|
|
|
Line(c, cnode, Node(c, s1)) |
|
|
|
|
for s1, s2 in assignments: # pass 1.5: process signal assignments |
|
|
|
|
if isinstance(s2, Tree) and s2.data == 'concatenation': |
|
|
|
|
for target, source in zip(self._signal_declarations[s1].names, s2.children): |
|
|
|
|
assign_wire(target, source) |
|
|
|
|
else: |
|
|
|
|
assign_wire(s1, s2) |
|
|
|
|
for stmt in args[2:]: # pass 2: connect signals to readers |
|
|
|
|
if isinstance(stmt, Instantiation): |
|
|
|
|
for p, s in stmt.pins.items(): |
|
|
|
@ -143,7 +149,7 @@ class VerilogTransformer(Transformer):
@@ -143,7 +149,7 @@ class VerilogTransformer(Transformer):
|
|
|
|
|
def start(args): return args[0] if len(args) == 1 else args |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GRAMMAR = """ |
|
|
|
|
GRAMMAR = r""" |
|
|
|
|
start: (module)* |
|
|
|
|
module: "module" name parameters ";" (_statement)* "endmodule" |
|
|
|
|
parameters: "(" [ _namelist ] ")" |
|
|
|
@ -153,16 +159,19 @@ GRAMMAR = """
@@ -153,16 +159,19 @@ GRAMMAR = """
|
|
|
|
|
inout: "inout" range? _namelist ";" |
|
|
|
|
tri: "tri" range? _namelist ";" |
|
|
|
|
wire: "wire" range? _namelist ";" |
|
|
|
|
assign: "assign" name "=" name ";" |
|
|
|
|
assign: "assign" lvalue "=" _expression ";" |
|
|
|
|
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";" |
|
|
|
|
pin: "." name "(" name? ")" |
|
|
|
|
range: "[" /[0-9]+/ ":" /[0-9]+/ "]" |
|
|
|
|
|
|
|
|
|
range: "[" /[0-9]+/ (":" /[0-9]+/)? "]" |
|
|
|
|
?lvalue: name range? |
|
|
|
|
_expression: name | concatenation |
|
|
|
|
concatenation: "{" _namelist "}" |
|
|
|
|
_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 ) |
|
|
|
|
COMMENT: "//" /[^\\n]*/ |
|
|
|
|
%ignore ( /\\r?\\n/ | COMMENT )+ |
|
|
|
|
%ignore /[\\t \\f]+/ |
|
|
|
|
name: ( /[a-z_][a-z0-9_\[\]]*/i | /\\[^\t \r\n]+[\t \r\n](\[[0-9]+\])?/i | /1'b0/i | /1'b1/i ) |
|
|
|
|
%import common.NEWLINE |
|
|
|
|
COMMENT: /\/\*(\*(?!\/)|[^*])*\*\// | /\(\*(\*(?!\))|[^*])*\*\)/ | "//" /(.)*/ NEWLINE |
|
|
|
|
%ignore ( /\r?\n/ | COMMENT )+ |
|
|
|
|
%ignore /[\t \f]+/ |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|