Skip to content

Commit 3692c2b

Browse files
committed
add(examples/vhdl/external_buffer)
1 parent 17fecdb commit 3692c2b

6 files changed

Lines changed: 208 additions & 2 deletions

File tree

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ matrix:
5959
- mkdir -p ghdl/build-llvm
6060
- curl -fsSL https://codeload.github.com/ghdl/ghdl/tar.gz/master | tar xzf - -C ghdl --strip-components=1
6161
- cd ghdl/build-llvm
62-
- ../configure --prefix=../../install-ghdl-llvm/ --with-llvm-config=llvm-config-3.5
62+
- ../configure --default-pic --prefix=../../install-ghdl-llvm/ --with-llvm-config=llvm-config-3.5
6363
- make
6464
- make install
6565
- cd ../../
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# This Source Code Form is subject to the terms of the Mozilla Public
2+
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
# You can obtain one at http://mozilla.org/MPL/2.0/.
4+
#
5+
# Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com
6+
7+
8+
from vunit import VUnit
9+
from sys import argv
10+
from os import popen
11+
from os.path import join, dirname
12+
import inspect
13+
from shutil import copyfile
14+
15+
16+
# TODO https://github.com/VUnit/vunit/issues/478
17+
def preconf(output_path):
18+
global opath
19+
opath = output_path
20+
return True
21+
22+
23+
global opath
24+
opath = ''
25+
src_path = join(dirname(__file__), "src")
26+
ext_srcs = join(dirname(inspect.getfile(VUnit)), 'vhdl', 'data_types', 'src', 'external')
27+
build_only = False
28+
if '--build' in argv:
29+
argv.remove('--build')
30+
build_only = True
31+
32+
std = "2008" # , "93"
33+
34+
ui = VUnit.from_argv(vhdl_standard=std, external=[True])
35+
36+
lib = ui.add_library("lib")
37+
lib.add_source_files(join(src_path, "test", "*.vhd"))
38+
39+
c_obj = join(src_path, 'test', 'main.o')
40+
41+
print(popen(' '.join([
42+
'gcc -fPIC -rdynamic',
43+
'-I', ext_srcs,
44+
'-c', join(src_path, '**', 'main.c'),
45+
'-o', c_obj
46+
])).read())
47+
48+
ui.set_sim_option("ghdl.elab_flags", [
49+
'-Wl,' + c_obj,
50+
'-Wl,-Wl,--version-script=' + join(ext_srcs, 'grt.ver')
51+
])
52+
53+
for tb in lib.get_test_benches(pattern='*', allow_empty=False):
54+
tb.set_pre_config(preconf)
55+
56+
if build_only:
57+
ui.set_sim_option("ghdl.elab_e", True)
58+
ui._args.elaborate = True
59+
try:
60+
ui.main()
61+
except SystemExit as exc:
62+
if exc.code is not 0:
63+
exit(exc.code)
64+
if build_only and len(opath):
65+
copyfile(join(opath, 'ghdl', 'args.txt'), join(dirname(__file__), 'args.txt'))
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
VHPI {
2+
global:
3+
main;
4+
read_char;
5+
write_char;
6+
read_integer;
7+
write_integer;
8+
set_string_ptr;
9+
get_string_ptr;
10+
set_intvec_ptr;
11+
get_intvec_ptr;
12+
local:
13+
*;
14+
};
15+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <stdint.h>
4+
#include <signal.h>
5+
6+
extern int ghdl_main (int argc, char **argv);
7+
8+
uint8_t *D[1];
9+
char is_allocated[1] = {0};
10+
const uint32_t length = 5;
11+
12+
void set_string_ptr(uint8_t id, uint8_t *p) {
13+
//printf("C set_string_ptr(%d, %p)\n", id, p);
14+
D[id] = p;
15+
is_allocated[id] = 1;
16+
}
17+
18+
uintptr_t get_string_ptr(uint8_t id) {
19+
//printf("C get_string_ptr(%d): %p\n", id, D[id]);
20+
return (uintptr_t)D[id];
21+
}
22+
23+
void write_char(uint8_t id, uint32_t i, uint8_t v ) {
24+
//printf("C write_char(%d, %d): %d\n", id, i, v);
25+
D[id][i] = v;
26+
}
27+
28+
uint8_t read_char(uint8_t id, uint32_t i) {
29+
//printf("C read_char(%d, %d): %d\n", id, i, D[id][i]);
30+
return D[id][i];
31+
}
32+
33+
void sigabrtHandler(int sig_num)
34+
{
35+
/* Reset handler to catch SIGINT next time. Refer http://en.cppreference.com/w/c/program/signal */
36+
signal(SIGABRT, sigabrtHandler);
37+
printf("\nSIGABRT caught!\n");
38+
fflush(stdout);
39+
}
40+
41+
static void exit_handler(void) {
42+
if (is_allocated[0] == 0) {
43+
int i;
44+
for(i=0; i<3*length; i++) {
45+
printf("%d: %d\n", i, D[0][i]);
46+
}
47+
free(D[0]);
48+
}
49+
}
50+
51+
int main(int argc, char **argv) {
52+
if (is_allocated[0] == 0) {
53+
D[0] = (uint8_t *) malloc(3*length*sizeof(uint8_t));
54+
if ( D[0] == NULL ) {
55+
perror("execution of malloc() failed!\n");
56+
return -1;
57+
}
58+
int i;
59+
for(i=0; i<length; i++) {
60+
D[0][i] = (i+1)*11;
61+
}
62+
for(i=0; i<3*length; i++) {
63+
printf("%d: %d\n", i, D[0][i]);
64+
}
65+
}
66+
67+
signal(SIGABRT, sigabrtHandler);
68+
69+
atexit(exit_handler);
70+
return ghdl_main(argc, argv);
71+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
-- This Source Code Form is subject to the terms of the Mozilla Public
2+
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
3+
-- You can obtain one at http://mozilla.org/MPL/2.0/.
4+
--
5+
-- Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com
6+
7+
--library vunit_lib;
8+
--context vunit_lib.vunit_context;
9+
10+
library vunit_lib;
11+
use vunit_lib.run_pkg.all;
12+
use vunit_lib.logger_pkg.all;
13+
use vunit_lib.byte_vector_ptr_pkg.all;
14+
15+
entity tb_external_buffer is
16+
generic ( runner_cfg : string );
17+
end entity;
18+
19+
architecture tb of tb_external_buffer is
20+
21+
constant block_len : natural := 5;
22+
23+
constant ebuf: byte_vector_ptr_t := new_byte_vector_ptr( 3*block_len, 1); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
24+
constant abuf: byte_vector_ptr_t := new_byte_vector_ptr( 3*block_len, -1); -- external through access (required VHPIDIRECT function 'get_string_ptr')
25+
26+
begin
27+
28+
main: process
29+
variable val: integer;
30+
begin
31+
test_runner_setup(runner, runner_cfg);
32+
info("Init test");
33+
for x in 0 to block_len-1 loop
34+
val := get(ebuf, x);
35+
set(ebuf, block_len+x, val+1);
36+
info("SET " & to_string(block_len+x) & ": " & to_string(val+1));
37+
end loop;
38+
for x in block_len to 2*block_len-1 loop
39+
val := get(abuf, x);
40+
set(abuf, block_len+x, val+2);
41+
info("SET " & to_string(block_len+x) & ": " & to_string(val+2));
42+
end loop;
43+
info("End test");
44+
test_runner_cleanup(runner);
45+
wait;
46+
end process;
47+
48+
end architecture;

vunit/test/acceptance/test_external_run_scripts.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import sys
1717
from vunit import ROOT
1818
from vunit.builtins import VHDL_PATH
19-
from vunit.test.common import has_simulator, check_report, simulator_is
19+
from vunit.test.common import has_simulator, check_report, simulator_is, simulator_check
2020

2121

2222
def simulator_supports_verilog():
@@ -115,6 +115,13 @@ def test_vhdl_array_axis_vcs_example_project(self):
115115
def test_vhdl_axi_dma_example_project(self):
116116
self.check(join(ROOT, "examples", "vhdl", "axi_dma", "run.py"))
117117

118+
@unittest.skipIf(
119+
simulator_check(lambda simclass: not simclass.supports_vhpi()),
120+
"This simulator/backend does not support interfacing with external C code"
121+
)
122+
def test_vhdl_external_buffer_project(self):
123+
self.check(join(ROOT, "examples", "vhdl", "external_buffer", "run.py"))
124+
118125
def test_vhdl_user_guide_example_project(self):
119126
self.check(join(ROOT, "examples", "vhdl", "user_guide", "run.py"), exit_code=1)
120127
check_report(self.report_file,

0 commit comments

Comments
 (0)