Added PyScModule to forward simulation phase callbacks
This commit is contained in:
parent
b1334a0689
commit
4381c9be32
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* PyScModule.cpp
|
||||||
|
*
|
||||||
|
* Created on: 08.06.2019
|
||||||
|
* Author: eyck
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PyScModule.h"
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
|
#include <python3.6/Python.h>
|
||||||
|
|
||||||
|
class TPyScriptThreadLocker {
|
||||||
|
PyGILState_STATE m_state;
|
||||||
|
public:
|
||||||
|
TPyScriptThreadLocker(): m_state(PyGILState_Ensure()) {}
|
||||||
|
~TPyScriptThreadLocker() { PyGILState_Release(m_state); }
|
||||||
|
};
|
||||||
|
|
||||||
|
scc::PyScModule::PyScModule(PyObject* self, const sc_core::sc_module_name& nm)
|
||||||
|
: sc_core::sc_module(nm)
|
||||||
|
, self(self)
|
||||||
|
{
|
||||||
|
if (! PyEval_ThreadsInitialized())
|
||||||
|
PyEval_InitThreads();
|
||||||
|
Py_INCREF(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
scc::PyScModule::~PyScModule() {
|
||||||
|
Py_DECREF(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scc::PyScModule::before_end_of_elaboration(){
|
||||||
|
invoke_callback("BeforeEndOfElaboration");
|
||||||
|
}
|
||||||
|
|
||||||
|
void scc::PyScModule::end_of_elaboration(){
|
||||||
|
invoke_callback("EndOfElaboration");
|
||||||
|
}
|
||||||
|
void scc::PyScModule::start_of_simulation(){
|
||||||
|
invoke_callback("StartOfSimulation");
|
||||||
|
}
|
||||||
|
|
||||||
|
void scc::PyScModule::end_of_simulation(){
|
||||||
|
invoke_callback("EndOfSimulation");
|
||||||
|
}
|
||||||
|
|
||||||
|
void scc::PyScModule::invoke_callback(const char* callback_name) {
|
||||||
|
// acquiring the GIL
|
||||||
|
PyGILState_STATE gstate;
|
||||||
|
gstate = PyGILState_Ensure();
|
||||||
|
if(PyObject_HasAttrString(self, callback_name)){
|
||||||
|
auto* func = PyObject_GetAttrString(self, callback_name);
|
||||||
|
PyObject_CallFunctionObjArgs(func, nullptr);
|
||||||
|
}
|
||||||
|
// Release the thread. No Python API allowed beyond this point.
|
||||||
|
PyGILState_Release(gstate);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* PyScModule.h
|
||||||
|
*
|
||||||
|
* Created on: 08.06.2019
|
||||||
|
* Author: eyck
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMPONENTS_PYSCMODULE_H_
|
||||||
|
#define COMPONENTS_PYSCMODULE_H_
|
||||||
|
#include <systemc>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
typedef struct _object PyObject;
|
||||||
|
|
||||||
|
namespace scc {
|
||||||
|
|
||||||
|
class PyScModule: public sc_core::sc_module {
|
||||||
|
public:
|
||||||
|
PyScModule(PyObject* self, const sc_core::sc_module_name& nm);
|
||||||
|
virtual ~PyScModule();
|
||||||
|
protected:
|
||||||
|
void before_end_of_elaboration() override;
|
||||||
|
void end_of_elaboration() override;
|
||||||
|
void start_of_simulation() override;
|
||||||
|
void end_of_simulation() override;
|
||||||
|
private:
|
||||||
|
void invoke_callback(const char*);
|
||||||
|
PyObject* self{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif /* COMPONENTS_PYSCMODULE_H_ */
|
|
@ -1,6 +1,7 @@
|
||||||
import json
|
import json
|
||||||
import cppyy
|
import cppyy
|
||||||
import os.path
|
import os.path
|
||||||
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import conans.client.conan_api as conan
|
import conans.client.conan_api as conan
|
||||||
|
@ -13,8 +14,6 @@ lang_symbols = {
|
||||||
14:'201402L',
|
14:'201402L',
|
||||||
17:'201703L'}
|
17:'201703L'}
|
||||||
lang_level=11
|
lang_level=11
|
||||||
'''
|
|
||||||
'''
|
|
||||||
|
|
||||||
sysIncludeDirs = set()
|
sysIncludeDirs = set()
|
||||||
|
|
||||||
|
@ -92,6 +91,7 @@ namespace sc_core { extern void pln(); }
|
||||||
if systemc_loaded: break;
|
if systemc_loaded: break;
|
||||||
if not interactive: cppyy.gbl.sc_core.pln()
|
if not interactive: cppyy.gbl.sc_core.pln()
|
||||||
cppyy.gbl.sc_core.sc_in_action=True
|
cppyy.gbl.sc_core.sc_in_action=True
|
||||||
|
_load_pythonization_lib()
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -120,7 +120,17 @@ def _load_systemc_cci():
|
||||||
cci_loaded=True
|
cci_loaded=True
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _load_pythonization_lib():
|
||||||
|
import pysysc
|
||||||
|
path = os.path.dirname(os.path.dirname(pysysc.__file__))
|
||||||
|
for file in os.listdir(path):
|
||||||
|
if file.endswith(".so"):
|
||||||
|
cppyy.load_library(os.path.join(path, file))
|
||||||
|
cppyy.include(os.path.join(path, "PyScModule.h"))
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
def add_library(file, lib):
|
def add_library(file, lib):
|
||||||
buf = io.StringIO()
|
buf = io.StringIO()
|
||||||
with redirect_stdout(buf), redirect_stderr(buf):
|
with redirect_stdout(buf), redirect_stderr(buf):
|
||||||
|
@ -150,8 +160,6 @@ def _pythonizor(clazz, name):
|
||||||
clazz.__repr__ = lambda self: repr(self.name())
|
clazz.__repr__ = lambda self: repr(self.name())
|
||||||
elif len(name) > 10 and name[:9] == 'sc_export<':
|
elif len(name) > 10 and name[:9] == 'sc_export<':
|
||||||
clazz.__repr__ = lambda self: repr(self.name())
|
clazz.__repr__ = lambda self: repr(self.name())
|
||||||
# else:
|
|
||||||
# print('not pythonizing', name)
|
|
||||||
|
|
||||||
# install the pythonizor as a callback on namespace 'Math' (default is the global namespace)
|
# install the pythonizor as a callback on namespace 'Math' (default is the global namespace)
|
||||||
cppyy.py.add_pythonization(_pythonizor, 'sc_core')
|
cppyy.py.add_pythonization(_pythonizor, 'sc_core')
|
||||||
|
|
|
@ -8,7 +8,6 @@ from builtins import getattr
|
||||||
import re
|
import re
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
import logging
|
import logging
|
||||||
import pysysc
|
|
||||||
|
|
||||||
class Mode(Enum):
|
class Mode(Enum):
|
||||||
SIM = 1
|
SIM = 1
|
||||||
|
@ -21,6 +20,8 @@ class Simulation(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run():
|
def run():
|
||||||
cpp.sc_core.sc_start()
|
cpp.sc_core.sc_start()
|
||||||
|
if not cpp.sc_core.sc_end_of_simulation_invoked():
|
||||||
|
cpp.sc_core.sc_stop()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def setup(log_level = logging.WARNING):
|
def setup(log_level = logging.WARNING):
|
||||||
|
|
18
setup.py
18
setup.py
|
@ -1,15 +1,26 @@
|
||||||
from setuptools import setup
|
from setuptools import setup, Extension
|
||||||
|
import os
|
||||||
|
|
||||||
def readme():
|
def readme():
|
||||||
with open('README.md') as f:
|
with open('README.md') as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
|
|
||||||
|
sysc_home = os.environ['SYSTEMC_HOME']
|
||||||
|
|
||||||
|
pysyscsc = Extension('pysyscsc',
|
||||||
|
define_macros = [('MAJOR_VERSION', '1'), ('MINOR_VERSION', '0')],
|
||||||
|
extra_compile_args = ['-std=c++11'],
|
||||||
|
include_dirs = [sysc_home+'/include'],
|
||||||
|
libraries = ['systemc'],
|
||||||
|
library_dirs = [sysc_home+'/lib'],
|
||||||
|
sources = ['PyScModule.cpp'])
|
||||||
|
|
||||||
|
|
||||||
setup(name='PySysC',
|
setup(name='PySysC',
|
||||||
version='0.1',
|
version='0.1',
|
||||||
description='Python SystemC binding',
|
description='Python SystemC binding',
|
||||||
long_description=readme(),
|
long_description=readme(),
|
||||||
|
ext_modules = [pysyscsc],
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 3 - Alpha',
|
'Development Status :: 3 - Alpha',
|
||||||
'License :: OSI Approved :: Apache Software License',
|
'License :: OSI Approved :: Apache Software License',
|
||||||
|
@ -22,11 +33,12 @@ setup(name='PySysC',
|
||||||
author_email='info@minres.com',
|
author_email='info@minres.com',
|
||||||
license='Apache-2.0',
|
license='Apache-2.0',
|
||||||
packages=['pysysc'],
|
packages=['pysysc'],
|
||||||
|
data_files=[('.',['PyScModule.h'])],
|
||||||
|
include_package_data=True,
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'cppyy',
|
'cppyy',
|
||||||
'conan'
|
'conan'
|
||||||
],
|
],
|
||||||
include_package_data=True,
|
|
||||||
test_suite='nose.collector',
|
test_suite='nose.collector',
|
||||||
tests_require=['nose'],
|
tests_require=['nose'],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue