Skip to content

Commit

Permalink
feat(external_buffer): add execution with Python ctypes
Browse files Browse the repository at this point in the history
  • Loading branch information
umarcor committed Apr 21, 2019
1 parent aea2f8b commit 9a9b74b
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 25 deletions.
67 changes: 59 additions & 8 deletions examples/vhdl/external_buffer/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,33 @@
#
# Copyright (c) 2014-2019, Lars Asplund [email protected]

from os import popen, mkdir
from os import popen
from os.path import join, dirname
from vunit import VUnit
import ctypes


def preconf(output_path):
global opath
opath = output_path
return True


def get_args(output_path):
args = [line.rstrip('\n') for line in open(join(output_path, 'ghdl', 'args.txt'))]
xargs = (ctypes.POINTER(ctypes.c_char) * (len(args) + 1))()
for i, arg in enumerate(args):
xargs[i] = ctypes.create_string_buffer(arg.encode('utf-8'))
return args[0], xargs


def unload(lib):
import _ctypes
# On GNU/Linux
_ctypes.dlclose(lib._handle)
# On Windows
#_ctypes.FreeLibrary(gbin._handle)


std = "2008"
#std = "93"
Expand All @@ -20,14 +44,41 @@
lib = ui.add_library("lib")
lib.add_source_files(join(src_path, "test", "*.vhd"))

try:
mkdir(join(src_path, '..', 'vunit_out'))
except OSError as exc:
pass

c_obj = join(src_path, '..', 'vunit_out', 'main.o')
c_obj = join(src_path, 'test', 'main.o')
print(popen('gcc -fPIC -rdynamic -c '+join(src_path, '**', 'main.c')+' -o '+c_obj).read())

ui.set_objects([c_obj])

ui.main()
for tb in lib.get_test_benches(pattern='*', allow_empty=False):
tb.set_pre_config(preconf)

ui.set_sim_option("ghdl.elab_e", True)
ui._args.elaborate = True
try:
ui.main()
except SystemExit as exc:
if exc.code is not 0:
exit(exc.code)

bin_path, xargv = get_args(opath)

print("\nREGULAR EXECUTION")
gbin = ctypes.CDLL(bin_path)
gbin.main(len(xargv)-1, xargv)
unload(gbin)

print("\nPYTHON ALLOCATION")
gbin = ctypes.CDLL(bin_path)

buf = ctypes.create_string_buffer(bytes([111, 122, 133, 144, 155]), 15)

for x in range(0, 15):
print("py " + str(x) + ": " + str(int.from_bytes(buf[x], "little")))

gbin.set_bytevec_addr(0, buf)
gbin.main(len(xargv)-1, xargv)

for x in range(0, 15):
print("py " + str(x) + ": " + str(int.from_bytes(buf[x], "little")))

unload(gbin)
42 changes: 25 additions & 17 deletions examples/vhdl/external_buffer/src/test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@
extern int ghdl_main (int argc, char **argv);

uint8_t *D[1];
char is_allocated[1] = {0};

void set_bytevec_addr(uint8_t id, uint8_t *p) {
//printf("C set_bytevec_addr(%d, %p)\n", id, p);
D[id] = p;
is_allocated[id] = 1;
}

uintptr_t get_bytevec_addr(uint8_t id) {
//printf("C get_addr(%d): %p\n", id, D[id]);
//printf("C get_bytevec_addr(%d): %p\n", id, D[id]);
return (uintptr_t)D[id];
}

Expand All @@ -24,29 +31,30 @@ uint8_t read_byte(uint8_t id, uint32_t i) {
int main(int argc, char **argv) {

const uint32_t length = 5;

D[0] = (uint8_t *) malloc(3*length*sizeof(uint8_t));
if ( D[0] == NULL ) {
perror("execution of malloc() failed!\n");
return -1;
}

int i;
for(i=0; i<length; i++) {
D[0][i] = (i+1)*11;
}

for(i=0; i<3*length; i++) {
printf("%d: %d\n", i, D[0][i]);
if (is_allocated[0] == 0) {
D[0] = (uint8_t *) malloc(3*length*sizeof(uint8_t));
if ( D[0] == NULL ) {
perror("execution of malloc() failed!\n");
return -1;
}
for(i=0; i<length; i++) {
D[0][i] = (i+1)*11;
}
for(i=0; i<3*length; i++) {
printf("%d: %d\n", i, D[0][i]);
}
}

ghdl_main(argc, argv);

for(i=0; i<3*length; i++) {
printf("%d: %d\n", i, D[0][i]);
if (is_allocated[0] == 0) {
for(i=0; i<3*length; i++) {
printf("%d: %d\n", i, D[0][i]);
}
free(D[0]);
}

free(D[0]);

return 0;
}

0 comments on commit 9a9b74b

Please sign in to comment.