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 5, 2019
1 parent 17fecdb commit 6fb5194
Show file tree
Hide file tree
Showing 6 changed files with 174 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
31 changes: 31 additions & 0 deletions examples/vhdl/external_buffer/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 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


src_path = join(dirname(__file__), "src")

ui = VUnit.from_argv(vhdl_standard="2008", 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',
'-c', join(src_path, '**', 'main.c'),
'-o', c_obj
])).read())

ui.set_sim_option("ghdl.elab_flags", ['-Wl,' + c_obj])

ui.main()
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 6fb5194

Please sign in to comment.