diff --git a/.pydevproject b/.pydevproject index 9d9a20d..240bc60 100644 --- a/.pydevproject +++ b/.pydevproject @@ -1,9 +1,16 @@ -PySysC Python 3.6.3 -python interpreter -3.6 - -/${PROJECT_DIR_NAME} - + + Default + + python interpreter + + 3.6 + + + + /${PROJECT_DIR_NAME} + + + diff --git a/README.md b/README.md index 86d41e6..8bbaa55 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A Python package to use SystemC from Python pyenv install 3.6.3 pyenv virtualenv 3.6.3 pysysc pyenv activate pysysc -STDCXX=11 MAKE_NPROCS=32 pip install --verbose --force-reinstall --ignore-installed --no-clean --build build --no-binary :all: cppyy +STDCXX=11 MAKE_NPROCS=32 pip install --verbose cppyy --no-binary=cppyy-cling pip install conan ``` diff --git a/pysysc/sccppyy.py b/pysysc/sccppyy.py index b9b6160..4c401b7 100644 --- a/pysysc/sccppyy.py +++ b/pysysc/sccppyy.py @@ -150,7 +150,7 @@ def add_sys_include_path(incl): def _pythonizor(clazz, name): # A pythonizor receives the freshly prepared bound C++ class, and a name stripped down to # the namespace the pythonizor is applied. Also accessible are clazz.__name__ (for the - # Python name) and clazz.__cppname__ (for the C++ name) + # Python name) and clazz.__cpp_name__ (for the C++ name) if name == 'sc_time': clazz.__repr__ = lambda self: repr(self.to_string()) clazz.__str__ = lambda self: self.to_string() diff --git a/pysysc/structural.py b/pysysc/structural.py index e83a2cb..e90f031 100644 --- a/pysysc/structural.py +++ b/pysysc/structural.py @@ -15,6 +15,53 @@ class Mode(Enum): mode=Mode.SIM +module_list = list() +connection_list = list() + +def dump_structure(): + mports=dict() + + def add_port(p, io): + mod = p.get_parent_object() + if mod not in mports: + mports[mod]=dict() + mports[mod]['in']=[] + mports[mod]['out']=[] + if not p in mports[mod][io]: + mports[mod][io].append(p) + + for c in connection_list: + add_port(c.source, 'out') + for t in c.targets: + add_port(t, 'in') + + with open("structure.dot", "w") as f: + f.write("""digraph structs { + rankdir=LR + node [shape=record];\n""") + for m in mports.keys(): + #struct3 [shape=record,label="hello\nworld |{ b |{c| d|e}| f}| g | h"]; + in_names=['<%s> %s'%(p.basename(), p.basename()) for p in mports[m]['in']] + out_names=['<%s> %s'%(p.basename(), p.basename()) for p in mports[m]['out']] + if len(in_names) == 0: + f.write(' %s [shape=record,label="{%s|{%s}}"];\n' % ( + m.name(), m.basename(), '|'.join(out_names))) + elif len(out_names) == 0: + f.write(' %s [shape=record,label="{{%s}|%s}"];\n' % ( + m.name(), '|'.join(in_names), m.basename())) + else: + f.write(' %s [shape=record,label="{{%s}|%s|{%s}}"];\n' % ( + m.name(), '|'.join(in_names), m.basename(), '|'.join(out_names))) + for c in connection_list: + attr = 'dir=both arrowhead=box arrowtail=obox' + if isinstance(c, Signal): + attr = 'dir=none' + src = '%s:%s' % (c.source.get_parent_object().name(), c.source.basename()) + for t in c.targets: + tgt = '%s:%s' % (t.get_parent_object().name(), t.basename()) + f.write(" %s -> %s [%s];\n" % (src, tgt, attr)) + f.write("}\n") + class Simulation(object): @staticmethod @@ -74,6 +121,7 @@ class Module(object): def __init__(self, clazz): self.cppclazz=clazz self.instance=None + module_list.append(self) def __getattr__(self, attr): if self.instance is None: @@ -91,6 +139,7 @@ class Connection(object): def __init__(self): self.source=None self.targets=[] + connection_list.append(self) def src(self, module_port): self.source=module_port @@ -101,6 +150,11 @@ class Connection(object): self.source.bind(module_port) return self + def cross(self, module_port_in, module_port_out): + self.targets.append(module_port_in) + self.source.bind(module_port_in) + return Connection().src(module_port_out) + class Signal(Connection): ''' classdocs @@ -118,7 +172,7 @@ class Signal(Connection): def src(self, module_port): self.source=module_port - port_class_name=type(module_port).__cppname__ + port_class_name=type(module_port).__cpp_name__ match = self._sc_inout_re.match(port_class_name) if match: self.data_type=match.group(1) @@ -138,3 +192,7 @@ class Signal(Connection): module_port.bind(self.signal) return self + def cross(self, module_port_in, module_port_out): + self.targets.append(module_port_in) + self.source.bind(module_port_in) + return Signal().src(module_port_out) diff --git a/tests/parsing.py b/tests/parsing.py new file mode 100644 index 0000000..791f820 --- /dev/null +++ b/tests/parsing.py @@ -0,0 +1,39 @@ +''' +Created on 03.01.2019 + +@author: eyck +''' +from cppyy_backend._cppyy_generator import CppyyGenerator +from clang.cindex import Config +from pprint import pprint +import glob +import os.path + +proj_dir='../../PySysC-SC/components' +flags=['-I/home/eyck/.conan/data/SystemC/2.3.2/minres/stable/package/672f3350f4be793d25afa19a6a77085e20d01ea5/include', + '-I'+proj_dir, + '-fvisibility=hidden', + '-D__PIC__', + '-Wno-macro-redefined', + '-std=c++11'] +Config.set_library_file('/usr/lib/x86_64-linux-gnu/libclang-6.0.so') +lib = Config().lib +import ctypes +from clang.cindex import Type +items = [ + ("clang_Type_getNumTemplateArguments", [Type], ctypes.c_size_t), +] +for item in items: + func = getattr(lib, item[0]) + if len(item) >= 2: + func.argtypes = item[1] + + if len(item) >= 3: + func.restype = item[2] + + if len(item) == 4: + func.errcheck = item[3] +g = CppyyGenerator(flags, dump_modules=True, dump_items=True, dump_includes=False, dump_privates=True, verbose=True) +mapping = g.create_mapping([os.path.join(proj_dir, 'initiator.h')]) + +pprint(mapping) \ No newline at end of file diff --git a/tests/systemc.py b/tests/systemc.py index dfacaa2..22bd614 100644 --- a/tests/systemc.py +++ b/tests/systemc.py @@ -23,8 +23,8 @@ v=cppyy.gbl.std.vector[int](10) n = cppyy.gbl.my_module() pp(sc_core.sc_time_stamp().to_string()) pp(n.simcontext().time_stamp().to_string()) -print(type(n.port).__name__ +", "+type(n.port).__cppname__) -print(type(n.sig).__name__+", "+type(n.sig).__cppname__) +print(type(n.port).__name__ +", "+type(n.port).__cpp_name__) +print(type(n.sig).__name__+", "+type(n.sig).__cpp_name__) #try: # cppyy.cppdef("""blah /* a comment */"""); diff --git a/tests/test_pysysc.py b/tests/test_pysysc.py new file mode 100644 index 0000000..9550411 --- /dev/null +++ b/tests/test_pysysc.py @@ -0,0 +1,65 @@ +''' +Created on 01.01.2019 + +@author: eyck +''' +import unittest +import json +import cppyy +import os.path +import pysysc as scpy +from cppyy import gbl as cpp + + +class Test(unittest.TestCase): + initialized=False + + def setUp(self): + proj_home='../PySysC-SC' + conan_res = scpy.read_config_from_conan(os.path.join(proj_home, 'conanfile.txt')) + scpy.load_systemc() + scpy.add_include_path(os.path.join(proj_home, 'components')) + scpy.add_library('components.h', os.path.join(proj_home, 'build/Debug/lib/libcomponents.so')) + + self.initiator = cpp.Initiator(cpp.sc_core.sc_module_name("initiator")) + self.memories = [cpp.Memory(cpp.sc_core.sc_module_name(name)) for name in ["mem0", "mem1", "mem2", "mem3"]] + self.router = cpp.Router[4](cpp.sc_core.sc_module_name("router")) + self.initiator.socket.bind(self.router.target_socket) + for idx,m in enumerate(self.memories): + self.router.initiator_socket.at(idx).bind(m.socket) + print("Initialized") + + def tearDown(self): + #cpp.sc_core.sc_stop() + pass + + + def testSCTimeRepr(self): + self.assertEqual(str(cpp.sc_core.sc_time_stamp()), '0 s') + + def testMembers(self): + members = scpy.get_members(initiator) + print("members") + methods = scpy.get_methods(initiator) + print("methods") + + ports = scpy.get_ports(initiator) + print("ports") + intors = scpy.get_inititator_sockets(initiator) + print("intors") + tgts = scpy.get_target_sockets(initiator) + print("tgts") + childs = scpy.get_submodules(initiator) + print("childs") + self.assertTrue(len(intors)==1, "Wrong numbers of initiator sockets") + + def testConnection(self): + self.assertFalse(isinstance(self.intors[0][0], cpp.sc_core.sc_object), " intor[0] connects to sc_object", ) + +# def testSim(self): +# cpp.sc_core.sc_in_action=True +# cpp.sc_core.sc_start() + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() \ No newline at end of file