Skip to content

Commit

Permalink
Merge fe4f6cf into 301cc9d
Browse files Browse the repository at this point in the history
  • Loading branch information
rsetaluri committed Sep 7, 2018
2 parents 301cc9d + fe4f6cf commit a280aad
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 37 deletions.
76 changes: 46 additions & 30 deletions magma/fromverilog.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from pyverilog.dataflow.visit import NodeVisitor

from .t import In, Out, InOut
from .bit import Bit
from .bit import Bit, BitKind
from .clock import Clock, ClockKind
from .array import Array
from .circuit import DeclareCircuit, DefineCircuit, EndDefine
import logging
Expand All @@ -33,7 +34,16 @@ def visit_ModuleDef(self, node):
self.nodes.append(node)
return node

def get_type(io):
def convert(input_type, target_type):
if isinstance(input_type, BitKind) and \
isinstance(target_type, ClockKind) and \
input_type.direction == target_type.direction:
return target_type
raise NotImplementedError(f"Conversion between {input_type} and "
"{target_type} not supported")


def get_type(io, type_map):
if isinstance(io, Input):
direction = In
elif isinstance(io, Output):
Expand All @@ -48,17 +58,23 @@ def get_type(io):
lsb = int(io.width.lsb.value)

type_ = Array(msb-lsb+1, Bit)
return direction(type_)

type_ = direction(type_)

if io.name in type_map:
type_ = convert(type_, type_map[io.name])

return type_


def ParseVerilogModule(node):
def ParseVerilogModule(node, type_map):
args = []
ports = []
for port in node.portlist.ports:
if isinstance(port, Ioport):
io = port.first
args.append(io.name)
args.append(get_type(io))
args.append(get_type(io, type_map))
elif isinstance(port, Port):
ports.append(port.name)
else:
Expand All @@ -73,14 +89,14 @@ def ParseVerilogModule(node):
if isinstance(first_child, (parser.Input, parser.Output, parser.Inout)) and \
first_child.name == port:
args.append(first_child.name)
args.append(get_type(first_child))
args.append(get_type(first_child, type_map))
break
else:
raise Exception(f"Could not find type declaration for port {port}")

return node.name, args

def FromVerilog(source, func, module=None):
def FromVerilog(source, func, type_map, module=None):
parser = VerilogParser()

ast = parser.parse(source)
Expand All @@ -97,7 +113,7 @@ def FromVerilog(source, func, module=None):
if module is not None and node.name != module:
continue
try:
name, args = ParseVerilogModule(node)
name, args = ParseVerilogModule(node, type_map)
circuit = func(name, *args)
if func == DefineCircuit:
# inline source
Expand All @@ -114,45 +130,45 @@ def FromVerilog(source, func, module=None):

return modules

def FromVerilogFile(file, func, module=None):
def FromVerilogFile(file, func, type_map, module=None):
if file is None:
return None
verilog = open(file).read()
return FromVerilog(verilog, func, module)
return FromVerilog(verilog, func, type_map, module)

def FromTemplatedVerilog(templatedverilog, func, **kwargs):
def FromTemplatedVerilog(templatedverilog, func, type_map, **kwargs):
verilog = Template(templatedverilog).render(**kwargs)
return FromVerilog(verilog, func)
return FromVerilog(verilog, func, type_map)

def FromTemplatedVerilogFile(file, func, **kwargs):
def FromTemplatedVerilogFile(file, func, type_map, **kwargs):
if file is None:
return None
templatedverilog = open(file).read()
return FromTemplatedVerilog(templatedverilog, func, **kwargs)
return FromTemplatedVerilog(templatedverilog, func, type_map, **kwargs)


def DeclareFromVerilog(source):
return FromVerilog(source, DeclareCircuit)
def DeclareFromVerilog(source, type_map={}):
return FromVerilog(source, DeclareCircuit, type_map)

def DeclareFromVerilogFile(file, module=None):
return FromVerilogFile(file, DeclareCircuit, module)
def DeclareFromVerilogFile(file, module=None, type_map={}):
return FromVerilogFile(file, DeclareCircuit, type_map, module)

def DeclareFromTemplatedVerilog(source, **kwargs):
return FromTemplatedVerilog(source, DeclareCircuit, **kwargs)
def DeclareFromTemplatedVerilog(source, type_map={}, **kwargs):
return FromTemplatedVerilog(source, DeclareCircuit, type_map, **kwargs)

def DeclareFromTemplatedVerilogFile(file, **kwargs):
return FromTemplatedVerilogFile(file, DeclareCircuit, **kwargs)
def DeclareFromTemplatedVerilogFile(file, type_map={}, **kwargs):
return FromTemplatedVerilogFile(file, DeclareCircuit, type_map, **kwargs)


def DefineFromVerilog(source):
return FromVerilog(source, DefineCircuit)
def DefineFromVerilog(source, type_map={}):
return FromVerilog(source, DefineCircuit, type_map)

def DefineFromVerilogFile(file, module=None):
return FromVerilogFile(file, DefineCircuit, module)
def DefineFromVerilogFile(file, module=None, type_map={}):
return FromVerilogFile(file, DefineCircuit, type_map, module)

def DefineFromTemplatedVerilog(source, **kwargs):
return FromTemplatedVerilog(source, DefineCircuit, **kwargs)
def DefineFromTemplatedVerilog(source, type_map={}, **kwargs):
return FromTemplatedVerilog(source, DefineCircuit, type_map, **kwargs)

def DefineFromTemplatedVerilogFile(file, **kwargs):
return FromTemplatedVerilogFile(file, DefineCircuit, **kwargs)
def DefineFromTemplatedVerilogFile(file, type_map={}, **kwargs):
return FromTemplatedVerilogFile(file, DefineCircuit, type_map, **kwargs)

37 changes: 30 additions & 7 deletions tests/test_verilog/test_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,44 @@
import os
import magma as m

def test_simple():

def full_path(filename):
file_path = os.path.dirname(__file__)
file_name = os.path.join(file_path, "simple.v")
with open(file_name, 'r') as f:
s = f.read()
return os.path.join(file_path, filename)


def test_simple():
path = full_path("simple.v")
with open(path, 'r') as f:
s = f.read()
v = DeclareFromVerilog(s)
top = v[0]
assert top.name == "top"
assert repr(top.IO) == "Interface(a, In(Bit), b, Out(Bit), c, InOut(Bit))"


def test_type_map():
path = full_path("simple.v")
with open(path, 'r') as f:
s = f.read()
type_map = {"a": m.In(m.Clock)}
v = DeclareFromVerilog(s, type_map)
top = v[0]
assert repr(top.IO) == "Interface(a, In(Clock), b, Out(Bit), c, InOut(Bit))"


def test_type_map_error():
path = full_path("simple.v")
with open(path, 'r') as f:
s = f.read()
type_map = {"a": m.In(m.Bits(4))}
v = DeclareFromVerilog(s, type_map)
assert len(v) == 0


def test_small():
file_path = os.path.dirname(__file__)
file_name = os.path.join(file_path, "small.v")
small = m.DeclareFromVerilogFile(file_name)[0]
path = full_path("small.v")
small = m.DeclareFromVerilogFile(path)[0]
for name in small.IO():
assert name in ["in", "out"]

Expand Down

0 comments on commit a280aad

Please sign in to comment.