Skip to content

Commit

Permalink
add(examples/vhdl/external_buffer)
Browse files Browse the repository at this point in the history
  • Loading branch information
umarcor committed Jun 4, 2019
1 parent 17fecdb commit 3692c2b
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ matrix:
- mkdir -p ghdl/build-llvm
- curl -fsSL https://codeload.github.com/ghdl/ghdl/tar.gz/master | tar xzf - -C ghdl --strip-components=1
- cd ghdl/build-llvm
- ../configure --prefix=../../install-ghdl-llvm/ --with-llvm-config=llvm-config-3.5
- ../configure --default-pic --prefix=../../install-ghdl-llvm/ --with-llvm-config=llvm-config-3.5
- make
- make install
- cd ../../
Expand Down
65 changes: 65 additions & 0 deletions examples/vhdl/external_buffer/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com


from vunit import VUnit
from sys import argv
from os import popen
from os.path import join, dirname
import inspect
from shutil import copyfile


# TODO https://github.com/VUnit/vunit/issues/478
def preconf(output_path):
global opath
opath = output_path
return True


global opath
opath = ''
src_path = join(dirname(__file__), "src")
ext_srcs = join(dirname(inspect.getfile(VUnit)), 'vhdl', 'data_types', 'src', 'external')
build_only = False
if '--build' in argv:
argv.remove('--build')
build_only = True

std = "2008" # , "93"

ui = VUnit.from_argv(vhdl_standard=std, external=[True])

lib = ui.add_library("lib")
lib.add_source_files(join(src_path, "test", "*.vhd"))

c_obj = join(src_path, 'test', 'main.o')

print(popen(' '.join([
'gcc -fPIC -rdynamic',
'-I', ext_srcs,
'-c', join(src_path, '**', 'main.c'),
'-o', c_obj
])).read())

ui.set_sim_option("ghdl.elab_flags", [
'-Wl,' + c_obj,
'-Wl,-Wl,--version-script=' + join(ext_srcs, 'grt.ver')
])

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

if build_only:
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)
if build_only and len(opath):
copyfile(join(opath, 'ghdl', 'args.txt'), join(dirname(__file__), 'args.txt'))
15 changes: 15 additions & 0 deletions examples/vhdl/external_buffer/src/grt.ver
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
VHPI {
global:
main;
read_char;
write_char;
read_integer;
write_integer;
set_string_ptr;
get_string_ptr;
set_intvec_ptr;
get_intvec_ptr;
local:
*;
};

71 changes: 71 additions & 0 deletions examples/vhdl/external_buffer/src/test/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>

extern int ghdl_main (int argc, char **argv);

uint8_t *D[1];
char is_allocated[1] = {0};
const uint32_t length = 5;

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

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

void write_char(uint8_t id, uint32_t i, uint8_t v ) {
//printf("C write_char(%d, %d): %d\n", id, i, v);
D[id][i] = v;
}

uint8_t read_char(uint8_t id, uint32_t i) {
//printf("C read_char(%d, %d): %d\n", id, i, D[id][i]);
return D[id][i];
}

void sigabrtHandler(int sig_num)
{
/* Reset handler to catch SIGINT next time. Refer http://en.cppreference.com/w/c/program/signal */
signal(SIGABRT, sigabrtHandler);
printf("\nSIGABRT caught!\n");
fflush(stdout);
}

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

int main(int argc, char **argv) {
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;
}
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]);
}
}

signal(SIGABRT, sigabrtHandler);

atexit(exit_handler);
return ghdl_main(argc, argv);
}
48 changes: 48 additions & 0 deletions examples/vhdl/external_buffer/src/test/tb_external_buffer.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
-- You can obtain one at http://mozilla.org/MPL/2.0/.
--
-- Copyright (c) 2014-2019, Lars Asplund lars.anders.asplund@gmail.com

--library vunit_lib;
--context vunit_lib.vunit_context;

library vunit_lib;
use vunit_lib.run_pkg.all;
use vunit_lib.logger_pkg.all;
use vunit_lib.byte_vector_ptr_pkg.all;

entity tb_external_buffer is
generic ( runner_cfg : string );
end entity;

architecture tb of tb_external_buffer is

constant block_len : natural := 5;

constant ebuf: byte_vector_ptr_t := new_byte_vector_ptr( 3*block_len, 1); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
constant abuf: byte_vector_ptr_t := new_byte_vector_ptr( 3*block_len, -1); -- external through access (required VHPIDIRECT function 'get_string_ptr')

begin

main: process
variable val: integer;
begin
test_runner_setup(runner, runner_cfg);
info("Init test");
for x in 0 to block_len-1 loop
val := get(ebuf, x);
set(ebuf, block_len+x, val+1);
info("SET " & to_string(block_len+x) & ": " & to_string(val+1));
end loop;
for x in block_len to 2*block_len-1 loop
val := get(abuf, x);
set(abuf, block_len+x, val+2);
info("SET " & to_string(block_len+x) & ": " & to_string(val+2));
end loop;
info("End test");
test_runner_cleanup(runner);
wait;
end process;

end architecture;
9 changes: 8 additions & 1 deletion vunit/test/acceptance/test_external_run_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import sys
from vunit import ROOT
from vunit.builtins import VHDL_PATH
from vunit.test.common import has_simulator, check_report, simulator_is
from vunit.test.common import has_simulator, check_report, simulator_is, simulator_check


def simulator_supports_verilog():
Expand Down Expand Up @@ -115,6 +115,13 @@ def test_vhdl_array_axis_vcs_example_project(self):
def test_vhdl_axi_dma_example_project(self):
self.check(join(ROOT, "examples", "vhdl", "axi_dma", "run.py"))

@unittest.skipIf(
simulator_check(lambda simclass: not simclass.supports_vhpi()),
"This simulator/backend does not support interfacing with external C code"
)
def test_vhdl_external_buffer_project(self):
self.check(join(ROOT, "examples", "vhdl", "external_buffer", "run.py"))

def test_vhdl_user_guide_example_project(self):
self.check(join(ROOT, "examples", "vhdl", "user_guide", "run.py"), exit_code=1)
check_report(self.report_file,
Expand Down

0 comments on commit 3692c2b

Please sign in to comment.