Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ addons:
- python3-dev
- python3-nose
- graphviz
- bison
- flex

before_install:
- source dmlc-core/scripts/travis/travis_setup_env.sh
- export PYTHONPATH=${PYTHONPATH}:${PWD}/python

install:
- source dmlc-core/scripts/travis/travis_setup_env.sh
- source tests/travis/setup.sh

script:
Expand Down
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ endif
include $(config)

# specify tensor path
.PHONY: clean all test doc pylint cpplint lint
.PHONY: clean all test doc pylint cpplint lint verilog

all: lib/libtvm.so lib/libtvm_runtime.so lib/libtvm.a

Expand Down Expand Up @@ -79,6 +79,9 @@ include tests/cpp/unittest.mk

test: $(TEST)

include verilog/verilog.mk
verilog: $(VER_LIBS)

build/%.o: src/%.cc
@mkdir -p $(@D)
$(CXX) $(CFLAGS) -MM -MT build/$*.o $< >build/$*.d
Expand All @@ -92,6 +95,8 @@ lib/libtvm_runtime.so: $(RUNTIME_DEP)
@mkdir -p $(@D)
$(CXX) $(CFLAGS) $(FRAMEWORKS) -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS)



lib/libtvm.a: $(ALL_DEP)
@mkdir -p $(@D)
ar crv $@ $(filter %.o, $?)
Expand All @@ -102,7 +107,7 @@ LIBHALIDEIR:
+ cd HalideIR; make lib/libHalideIR.a ; cd $(ROOTDIR)

cpplint:
python2 dmlc-core/scripts/lint.py tvm cpp include src
python2 dmlc-core/scripts/lint.py tvm cpp include src verilog

pylint:
pylint python/tvm --rcfile=$(ROOTDIR)/tests/lint/pylintrc
Expand Down
2 changes: 2 additions & 0 deletions include/tvm/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class Channel : public NodeRef {
* \return the pointer to the internal node container
*/
inline const ChannelNode* operator->() const;
// The container type
using ContainerType = ChannelNode;
};

/*!
Expand Down
233 changes: 233 additions & 0 deletions python/tvm/addon/verilog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
"""Information about nnvm."""
from __future__ import absolute_import

import subprocess
import sys
import os

from .. import _api_internal
from .._base import string_types
from .._ctypes._node import NodeBase, register_node
from . import testing

@register_node
class VPISession(NodeBase):
"""Verilog session"""
def __init__(self, handle):
super(VPISession, self).__init__(handle)
self.proc = None
self.execpath = None

def __del__(self):
self.proc.kill()
super(VPISession, self).__del__()

def arg(self, index):
"""Get handle passed to host session.

Parameters
----------
index : int
The index value.

Returns
-------
handle : VPIHandle
The handle
"""
return _api_internal._vpi_SessGetArg(self, index)

def __getitem__(self, name):
if not isinstance(name, string_types):
raise ValueError("have to be string types")
return _api_internal._vpi_SessGetHandleByName(self, name)

def __getattr__(self, name):
return _api_internal._vpi_SessGetHandleByName(self, name)

def yield_until_posedge(self):
"""Yield until next posedge"""
return _api_internal._vpi_SessYield(self)

def shutdown(self):
"""Shutdown the simulator"""
return _api_internal._vpi_SessShutdown(self)


@register_node
class VPIHandle(NodeBase):
"""Handle to a verilog variable."""
def __init__(self, handle):
super(VPIHandle, self).__init__(handle)
self._name = None
self._size = None

def get_int(self):
"""Get integer value from handle.

Returns
-------
value : int
"""
return _api_internal._vpi_HandleGetInt(self)

def put_int(self, value):
"""Put integer value to handle.

Parameters
----------
value : int
The value to put
"""
return _api_internal._vpi_HandlePutInt(self, value)

@property
def name(self):
if self._name is None:
self._name = _api_internal._vpi_HandleGetName(self)
return self._name

@property
def size(self):
if self._size is None:
self._size = _api_internal._vpi_HandleGetSize(self)
return self._size

def __getitem__(self, name):
if not isinstance(name, string_types):
raise ValueError("have to be string types")
return _api_internal._vpi_HandleGetHandleByName(self, name)

def __getattr__(self, name):
return _api_internal._vpi_HandleGetHandleByName(self, name)


def _find_vpi_path():
curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__)))
api_path = os.path.join(curr_path, '../../../lib/')
vpi_path = [curr_path, api_path]
vpi_path = [os.path.join(p, 'tvm_vpi.vpi') for p in vpi_path]
vpi_found = [p for p in vpi_path if os.path.exists(p) and os.path.isfile(p)]
if vpi_found:
return os.path.dirname(vpi_found[0])
else:
raise ValueError("Cannot find tvm_vpi.vpi, make sure you did `make verilog`")

def search_path():
"""Get the search directory."""
curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__)))
ver_path = [os.path.join(curr_path, '../../../verilog/')]
ver_path += [os.path.join(curr_path, '../../../tests/verilog/')]
return ver_path


def find_file(file_name):
"""Find file in the search directories.

Parameters
----------
file_name : str
The file name

Return
------
file_name : str
The absolute path to the file, raise Error if cannot find it.
"""
ver_path = search_path()
flist = [os.path.join(p, file_name) for p in ver_path]
found = [p for p in flist if os.path.exists(p) and os.path.isfile(p)]
if len(found):
return found[0]
else:
raise ValueError("Cannot find %s in %s" % (file_name, flist))


def compile_file(file_name, file_target, options=None):
"""Compile verilog via iverilog

Parameters
----------
file_name : str or list of str
The cuda code.

file_target : str
The target file.
"""
cmd = ["iverilog"]
for path in search_path():
cmd += ["-I%s" % path]

cmd += ["-o", file_target]
if options:
cmd += options

if isinstance(file_name, string_types):
file_name = [file_name]
cmd += file_name
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
(out, _) = proc.communicate()

if proc.returncode != 0:
raise ValueError("Compilation error:\n%s" % out)


def session(file_name):
"""Create a new iverilog session by compile the file.

Parameters
----------
file_name : str or list of str
The name of the file

Returns
-------
sess : VPISession
The created session.
"""
if isinstance(file_name, string_types):
file_name = [file_name]

for name in file_name:
if not os.path.exists(name):
raise ValueError("Cannot find file %s" % name)

path = testing.tempdir()
target = path.relpath(os.path.basename(file_name[0].rsplit(".", 1)[0]))
compile_file(file_name, target)
vpi_path = _find_vpi_path()

cmd = ["vvp"]
cmd += ["-M", vpi_path]
cmd += ["-m", "tvm_vpi"]
cmd += [target]
env = os.environ.copy()

read_device, write_host = os.pipe()
read_host, write_device = os.pipe()

if sys.platform == "win32":
import msvcrt
env['TVM_DREAD_PIPE'] = str(msvcrt.get_osfhandle(read_device))
env['TVM_DWRITE_PIPE'] = str(msvcrt.get_osfhandle(write_device))
read_host = msvcrt.get_osfhandle(read_host)
write_host = msvcrt.get_osfhandle(write_host)
else:
env['TVM_DREAD_PIPE'] = str(read_device)
env['TVM_DWRITE_PIPE'] = str(write_device)

env['TVM_HREAD_PIPE'] = str(read_host)
env['TVM_HWRITE_PIPE'] = str(write_host)

proc = subprocess.Popen(cmd, env=env, close_fds=False)
# close device side pipe
os.close(read_device)
os.close(write_device)

sess = _api_internal._vpi_SessMake(read_host, write_host)
sess.proc = proc
sess.execpath = path
return sess
1 change: 1 addition & 0 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Header files in include are public APIs that share across modules.
There can be internal header files within each module that sit in src.

The current code modules in src.
- common Internal common utilities.
- api API function registration
- lang The definition of DSL related data structure
- arithmetic Arithmetic expression and set simplification
Expand Down
Loading