Skip to content

Commit 9a9b74b

Browse files
committed
feat(external_buffer): add execution with Python ctypes
1 parent aea2f8b commit 9a9b74b

2 files changed

Lines changed: 84 additions & 25 deletions

File tree

examples/vhdl/external_buffer/run.py

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,33 @@
44
#
55
# Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com
66

7-
from os import popen, mkdir
7+
from os import popen
88
from os.path import join, dirname
99
from vunit import VUnit
10+
import ctypes
11+
12+
13+
def preconf(output_path):
14+
global opath
15+
opath = output_path
16+
return True
17+
18+
19+
def get_args(output_path):
20+
args = [line.rstrip('\n') for line in open(join(output_path, 'ghdl', 'args.txt'))]
21+
xargs = (ctypes.POINTER(ctypes.c_char) * (len(args) + 1))()
22+
for i, arg in enumerate(args):
23+
xargs[i] = ctypes.create_string_buffer(arg.encode('utf-8'))
24+
return args[0], xargs
25+
26+
27+
def unload(lib):
28+
import _ctypes
29+
# On GNU/Linux
30+
_ctypes.dlclose(lib._handle)
31+
# On Windows
32+
#_ctypes.FreeLibrary(gbin._handle)
33+
1034

1135
std = "2008"
1236
#std = "93"
@@ -20,14 +44,41 @@
2044
lib = ui.add_library("lib")
2145
lib.add_source_files(join(src_path, "test", "*.vhd"))
2246

23-
try:
24-
mkdir(join(src_path, '..', 'vunit_out'))
25-
except OSError as exc:
26-
pass
27-
28-
c_obj = join(src_path, '..', 'vunit_out', 'main.o')
47+
c_obj = join(src_path, 'test', 'main.o')
2948
print(popen('gcc -fPIC -rdynamic -c '+join(src_path, '**', 'main.c')+' -o '+c_obj).read())
3049

3150
ui.set_objects([c_obj])
3251

33-
ui.main()
52+
for tb in lib.get_test_benches(pattern='*', allow_empty=False):
53+
tb.set_pre_config(preconf)
54+
55+
ui.set_sim_option("ghdl.elab_e", True)
56+
ui._args.elaborate = True
57+
try:
58+
ui.main()
59+
except SystemExit as exc:
60+
if exc.code is not 0:
61+
exit(exc.code)
62+
63+
bin_path, xargv = get_args(opath)
64+
65+
print("\nREGULAR EXECUTION")
66+
gbin = ctypes.CDLL(bin_path)
67+
gbin.main(len(xargv)-1, xargv)
68+
unload(gbin)
69+
70+
print("\nPYTHON ALLOCATION")
71+
gbin = ctypes.CDLL(bin_path)
72+
73+
buf = ctypes.create_string_buffer(bytes([111, 122, 133, 144, 155]), 15)
74+
75+
for x in range(0, 15):
76+
print("py " + str(x) + ": " + str(int.from_bytes(buf[x], "little")))
77+
78+
gbin.set_bytevec_addr(0, buf)
79+
gbin.main(len(xargv)-1, xargv)
80+
81+
for x in range(0, 15):
82+
print("py " + str(x) + ": " + str(int.from_bytes(buf[x], "little")))
83+
84+
unload(gbin)

examples/vhdl/external_buffer/src/test/main.c

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@
55
extern int ghdl_main (int argc, char **argv);
66

77
uint8_t *D[1];
8+
char is_allocated[1] = {0};
9+
10+
void set_bytevec_addr(uint8_t id, uint8_t *p) {
11+
//printf("C set_bytevec_addr(%d, %p)\n", id, p);
12+
D[id] = p;
13+
is_allocated[id] = 1;
14+
}
815

916
uintptr_t get_bytevec_addr(uint8_t id) {
10-
//printf("C get_addr(%d): %p\n", id, D[id]);
17+
//printf("C get_bytevec_addr(%d): %p\n", id, D[id]);
1118
return (uintptr_t)D[id];
1219
}
1320

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

2633
const uint32_t length = 5;
27-
28-
D[0] = (uint8_t *) malloc(3*length*sizeof(uint8_t));
29-
if ( D[0] == NULL ) {
30-
perror("execution of malloc() failed!\n");
31-
return -1;
32-
}
33-
3434
int i;
35-
for(i=0; i<length; i++) {
36-
D[0][i] = (i+1)*11;
37-
}
3835

39-
for(i=0; i<3*length; i++) {
40-
printf("%d: %d\n", i, D[0][i]);
36+
if (is_allocated[0] == 0) {
37+
D[0] = (uint8_t *) malloc(3*length*sizeof(uint8_t));
38+
if ( D[0] == NULL ) {
39+
perror("execution of malloc() failed!\n");
40+
return -1;
41+
}
42+
for(i=0; i<length; i++) {
43+
D[0][i] = (i+1)*11;
44+
}
45+
for(i=0; i<3*length; i++) {
46+
printf("%d: %d\n", i, D[0][i]);
47+
}
4148
}
4249

4350
ghdl_main(argc, argv);
4451

45-
for(i=0; i<3*length; i++) {
46-
printf("%d: %d\n", i, D[0][i]);
52+
if (is_allocated[0] == 0) {
53+
for(i=0; i<3*length; i++) {
54+
printf("%d: %d\n", i, D[0][i]);
55+
}
56+
free(D[0]);
4757
}
4858

49-
free(D[0]);
50-
5159
return 0;
5260
}

0 commit comments

Comments
 (0)