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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Test build
run: |
python3 -m venv py
./py/bin/pip install ivpm pytest pytest-fv
./py/bin/pip install -U ivpm pytest pytest-dfm dv-flow-libhdlsim
./py/bin/python3 -m ivpm update -a
./packages/python/bin/python3 setup.py bdist_wheel
- name: Run tests
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,4 @@ results.xml
*.bk

examples/call/dpi/call_sv_bfm/call_sv_bfm_pkg.sv
rundir/
6 changes: 6 additions & 0 deletions doc/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@

## 0.0.3
- (#29) - Resolve issues with tasks and Python GIL
- (#22) - Resolve return value issue
- () - Add support for AMD Xilinx Xsim simulator
- () - Move tests over to use the DV Flow Manager PyTest extension

## 0.0.2
- (#25) - Correct issue passing string-type parameters

Expand Down
4 changes: 3 additions & 1 deletion examples/call/dpi/call_sv_bfm/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

pyhdl-if
cocotb
dv-flow-mgr
dv-flow-libhdlsim

14 changes: 10 additions & 4 deletions ivpm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@ package:
deps:
- name: pytest
src: pypi
- name: pytest-fv
url: https://github.com/fvutils/pytest-fv.git
- name: cython
src: pypi
- name: build
src: pypi
- name: setuptools_scm
src: pypi
- name: pytest-dfm
url: https://github.com/dv-flow/pytest-dfm.git
- name: dv-flow-libhdlsim
url: https://github.com/dv-flow/dv-flow-libhdlsim.git
- name: pytypeworks
url: https://github.com/mballance-utils/pytypeworks.git
- name: pyvsc-dataclasses
url: https://github.com/vsc-tools/pyvsc-dataclasses.git
- name: fusesoc
url: https://github.com/olofk/fusesoc.git
- name: iverilog
url: https://github.com/pss-hands-on/iverilog-bin/releases/download/v12.0/iverilog-maylinux2014-12.0.tar.gz
- name: verilator
Expand Down
7 changes: 5 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import sysconfig
from setuptools import Extension, setup, find_namespace_packages

version="0.0.2"
version="0.0.3"

proj_dir = os.path.dirname(os.path.abspath(__file__))
pythondir = os.path.join(proj_dir, "src")
Expand Down Expand Up @@ -105,7 +105,10 @@
],
'ivpm.pkginfo': [
'pyhdl-if = hdl_if.pkginfo:PkgInfo'
]
],
'dv_flow.mgr': [
'pyhdl-if = hdl_if.dfm.__ext__'
],
},
ext_modules=[ ext ]
)
Expand Down
133 changes: 131 additions & 2 deletions src/entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,29 @@ extern "C" {
#endif

static lib_h_t _python_lib = 0;

static lib_h_t init_python();

/**
* The following ensures that this DPI library has a dependency
* on DPI-exported symbols. This ensures that Python is able
* to find the exports
*/
int pyhdl_pi_if_RegisterTimeCB();
int pyhdl_call_if_invoke_hdl_f(void);
int pyhdl_call_if_invoke_hdl_t(void);
int pyhdl_call_if_response_py_t(void);

void *funcs[] = {
&pyhdl_pi_if_RegisterTimeCB,
&pyhdl_call_if_invoke_hdl_f,
&pyhdl_call_if_invoke_hdl_t,
&pyhdl_call_if_response_py_t,
};

void *get_dpiexport_funcs() {
return funcs;
}

//typedef void *PyObject;

/*******************************************************************
Expand Down Expand Up @@ -234,7 +254,7 @@ lib_h_t find_loaded_lib(const char *sym) {
char mapfile_path[256];
FILE *map_fp;

DEBUG("find_loaded_lib(linux) %s", sym);
DEBUG("--> find_loaded_lib(linux) %s", sym);

// First, try loading the executable
{
Expand All @@ -244,6 +264,7 @@ lib_h_t find_loaded_lib(const char *sym) {
DEBUG("returning %p", ret);
return ret;
} else {
DEBUG("didn't find symbol \"%s\" in the executable\n", sym);
ret = 0;
}
}
Expand Down Expand Up @@ -299,11 +320,14 @@ lib_h_t find_loaded_lib(const char *sym) {
free(path_s);
}

DEBUG("<-- find_loaded_lib(linux) %s %p", sym, ret);

return ret;
}

lib_h_t check_lib(const char *path, const char *sym) {
lib_h_t ret = 0;
DEBUG("--> check_lib(%s, %s)", path, sym);
lib_h_t lib = dlopen(path, RTLD_LAZY);
if (lib) {
void *sym_h = dlsym(lib, sym);
Expand All @@ -314,11 +338,53 @@ lib_h_t check_lib(const char *path, const char *sym) {
ret = lib;
}
}
DEBUG("<-- check_lib(%s, %s) %p", path, sym, ret);
return ret;
}

#endif

char *clean_env(const char *name, const char *omit) {
const char *value = getenv(name);
char *new_value;
const char *cp, *cpn;
int first_entry = 1;

if (!value || !value[0]) {
return 0;
}

cp = value;

new_value = (char *)malloc(strlen(name)+strlen(value)+2);
strcpy(new_value, name);
strcat(new_value, "=");

while (cp && *cp) {
cpn = strchr(cp, ':');
if (!cpn) {
cpn = cp + strlen(cp);
}

// Check if this path starts with pythonhome
if (strncmp(cp, omit, strlen(omit)) != 0) {
if (!first_entry) {
strcat(new_value, ":");
}
strncat(new_value, cp, cpn - cp);
first_entry = 0;
}

if (*cpn == ':') {
cp = cpn + 1;
} else {
cp = NULL;
}
}

return new_value;
}

#ifdef _WIN32
#else
lib_h_t find_config_python_lib() {
Expand All @@ -342,6 +408,62 @@ lib_h_t find_config_python_lib() {
fprintf(stdout, "PyHDL-IF Note: Using Python interpreter \"%s\", specified by $PYHDL_IF_PYTHON\n",
python);
fflush(stdout);
const char *pythonhome = getenv("PYTHONHOME");
if (pythonhome && pythonhome[0]) {
const char *pythonpath = getenv("PYTHONPATH");
const char *ldlibrarypath = getenv("LD_LIBRARY_PATH");
const char *path = getenv("PATH");

fprintf(stdout, "PyHDL-IF Note: Clearing PYTHONHOME and cleaning PYTHONPATH\n");
fflush(stdout);

{
char *new_pythonpath = clean_env("PYTHONPATH", pythonhome);
if (new_pythonpath) {
fprintf(stdout, "PyHDL-IF Note: Setting PYTHONPATH to \"%s\"\n", new_pythonpath);
putenv(new_pythonpath);
}
}
{
char *new_ldlibrarypath = clean_env("LD_LIBRARY_PATH", pythonhome);
if (new_ldlibrarypath) {
fprintf(stdout, "PyHDL-IF Note: Setting LD_LIBRARY_PATH to \"%s\"\n", new_ldlibrarypath);
putenv(new_ldlibrarypath);
}
}

{
char *new_path = clean_env("PATH", pythonhome);
if (new_path) {
fprintf(stdout, "PyHDL-IF Note: Setting PATH to \"%s\"\n", new_path);
putenv(new_path);
}
}

putenv(strdup("PYTHON="));
putenv(strdup("PYTHONHOME="));
}

// Now, add the new Python interpreter to the PATH
{
char *python_dir = strdup(python);
char *slash = strrchr(python_dir, '/');
char *new_path;
if (slash) {
*slash = 0; // Remove the filename
}

DEBUG("Python directory: %s", python_dir);
new_path = (char *)malloc(strlen(python_dir)+strlen(getenv("PATH"))+16);
strcpy(new_path, "PATH=");
strcat(new_path, python_dir);
strcat(new_path, ":");
strcat(new_path, getenv("PATH"));
DEBUG("New PATH: %s", new_path);
putenv(new_path);
free(python_dir);
}

}

args[0] = python;
Expand All @@ -350,8 +472,15 @@ lib_h_t find_config_python_lib() {
args[3] = 0;

{
int i;
extern char **environ;
const char *ld_library_path = getenv("LD_LIBRARY_PATH");
DEBUG("LD_LIBRARY_PATH: %s", ld_library_path?ld_library_path:"null");

for (i=0; environ[i]; i++) {
DEBUG("environ[%d]: %s", i, environ[i]);
}

}

(void)pipe(cout_pipe);
Expand Down
1 change: 1 addition & 0 deletions src/hdl_if/cmd/cmd_api_gen_sv.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __call__(self, args):
gen = GenSVClass(fp, uvm=args.uvm)

if args.package is not None:
gen.println('`include "pyhdl_if_macros.svh"')
gen.println("package %s;" % args.package)
gen.inc_ind()

Expand Down
14 changes: 14 additions & 0 deletions src/hdl_if/dfm/__ext__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@


print("__ext__")

def dfm_packages():
"""Returns the DFM packages"""
import os

dfm_dir = os.path.dirname(os.path.abspath(__file__))

return {
'pyhdl-if': os.path.join(dfm_dir, "flow.dv"),
}

Empty file added src/hdl_if/dfm/__init__.py
Empty file.
46 changes: 46 additions & 0 deletions src/hdl_if/dfm/api_gen_sv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import os
import sys
from dv_flow.mgr import TaskRunCtxt, TaskDataInput, TaskDataResult, FileSet

async def APIGenSV(runner, input) -> None:

env = runner.env.copy()

if input.params.pythonpath:
for path in input.params.pythonpath:
if "PYTHONPATH" not in env:
env["PYTHONPATH"] = path
else:
env["PYTHONPATH"] += os.pathsep + path

status = 0

cmd = [
sys.executable,
'-m', 'hdl_if',
'api-gen-sv'
]

for m in input.params.modules:
cmd.extend(['-m', m])

if input.params.pkgname:
cmd.extend(['--package', input.params.pkgname])

filename = input.params.filename

cmd.extend(['-o', os.path.join(input.rundir, filename)])

status |= await runner.exec(cmd, env=env)

output = []
output.append(FileSet(
basedir=input.rundir,
files=[filename],
filetype="systemVerilogSource"
))

return TaskDataResult(
status=status,
output=output
)
16 changes: 16 additions & 0 deletions src/hdl_if/dfm/dpi_lib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import os
from dv_flow.mgr import TaskDataInput, TaskRunCtxt, TaskDataResult, FileSet

async def DpiLib(ctxt : TaskRunCtxt, input : TaskDataInput) -> TaskDataResult:
from hdl_if import get_entry
entry = get_entry()

return TaskDataResult(
status=0,
output=[
FileSet(
filetype="systemVerilogDPI",
basedir=os.path.dirname(entry),
files=[os.path.basename(entry)])
]
)
Loading
Loading