Skip to content

Commit d9d4b51

Browse files
committed
examples/vhdl/external_buffer: add cp.py run script and tbs
1 parent 8e5095d commit d9d4b51

6 files changed

Lines changed: 225 additions & 1 deletion

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
from vunit import VUnit
8+
from os import popen
9+
from os.path import join, dirname
10+
11+
src_path = join(dirname(__file__), 'src')
12+
13+
c_obj = join(src_path, 'cp.o')
14+
# Compile C application to an object
15+
print(popen(' '.join([
16+
'gcc', '-fPIC',
17+
'-c', join(src_path, 'cp.c'),
18+
'-o', c_obj
19+
])).read())
20+
21+
# Enable the external feature for strings
22+
vu = VUnit.from_argv(vhdl_standard='2008', compile_builtins=False)
23+
vu.add_builtins({'string': True})
24+
25+
lib = vu.add_library('lib')
26+
lib.add_source_files(join(src_path, 'tb_extcp_*.vhd'))
27+
28+
# Add the C object to the elaboration of GHDL
29+
vu.set_sim_option('ghdl.elab_flags', ['-Wl,' + c_obj])
30+
31+
vu.main()

examples/vhdl/external_buffer/run.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
vu.add_builtins({'string': True})
4545

4646
lib = vu.add_library('lib')
47-
lib.add_source_files(join(src_path, '*.vhd'))
47+
lib.add_source_files(join(src_path, 'tb_ext_*.vhd'))
4848

4949
# Add the C object to the elaboration of GHDL
5050
vu.set_sim_option('ghdl.elab_flags', ['-Wl,' + c_obj])
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
External Buffer
3+
4+
Interfacing with foreign languages (C) through VHPIDIRECT:
5+
https://ghdl.readthedocs.io/en/latest/using/Foreign.html
6+
7+
Two arrays of type uint8_t are allocated and some values are written to the first.
8+
Then, the VHDL simulation is executed, where the (external) array/buffer
9+
is used. When the simulation is finished, the results are checked. The content of
10+
the buffer is printed both before and after the simulation.
11+
12+
NOTE: This file is expected to be used along with tb_extcp_byte_vector.vhd or tb_extcp_string.vhd
13+
*/
14+
15+
#include <stdio.h>
16+
#include <stdlib.h>
17+
#include <stdint.h>
18+
19+
extern int ghdl_main (int argc, char **argv);
20+
21+
uint8_t *D[1];
22+
const uint32_t length = 10;
23+
24+
// Check procedure, to be executed when GHDL exits.
25+
// The simulation is expected to copy the first 1/3 elements to positions [1/3, 2/3),
26+
// while incrementing each value by one, and then copy elements from [1/3, 2/3) to
27+
// [2/3, 3/3), while incrementing each value by two.
28+
static void exit_handler(void) {
29+
int i, j, z, k;
30+
uint8_t expected, got;
31+
k = 0;
32+
33+
for(i=0; i<length; i++) {
34+
expected = D[0][i];
35+
got = D[1][i];
36+
if (expected != got) {
37+
printf("check error %d: %d %d\n", i, expected, got);
38+
exit(1);
39+
}
40+
printf("%d: %d\n", i, got);
41+
}
42+
43+
free(D[0]);
44+
free(D[1]);
45+
}
46+
47+
// Main entrypoint of the application
48+
int main(int argc, char **argv) {
49+
// Allocate two buffers
50+
int i;
51+
for(i=0; i<2; i++) {
52+
D[i] = (uint8_t *) malloc(length*sizeof(uint8_t));
53+
if ( D[i] == NULL ) {
54+
perror("execution of malloc() failed!\n");
55+
return -1;
56+
}
57+
}
58+
// Initialize the first buffer
59+
for(i=0; i<length; i++) {
60+
D[0][i] = (i+1)*11;
61+
}
62+
// Print all the buffer
63+
for(i=0; i<length; i++) {
64+
printf("%d: %d\n", i, D[0][i]);
65+
}
66+
67+
// Register a function to be called when GHDL exits
68+
atexit(exit_handler);
69+
70+
// Start the simulation
71+
return ghdl_main(argc, argv);
72+
}
73+
74+
// External through access (mode = extacc)
75+
76+
void set_string_ptr(uint8_t id, uint8_t *p) {
77+
//printf("C set_string_ptr(%d, %p)\n", id, p);
78+
D[id] = p;
79+
}
80+
81+
uintptr_t get_string_ptr(uint8_t id) {
82+
//printf("C get_string_ptr(%d): %p\n", id, D[id]);
83+
return (uintptr_t)D[id];
84+
}
85+
86+
// External through functions (mode = extfnc)
87+
88+
void write_char(uint8_t id, uint32_t i, uint8_t v ) {
89+
//printf("C write_char(%d, %d): %d\n", id, i, v);
90+
D[id][i] = v;
91+
}
92+
93+
uint8_t read_char(uint8_t id, uint32_t i) {
94+
//printf("C read_char(%d, %d): %d\n", id, i, D[id][i]);
95+
return D[id][i];
96+
}
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+
-- NOTE: This file is expected to be used along with foreign languages (C)
8+
-- through VHPIDIRECT: https://ghdl.readthedocs.io/en/latest/using/Foreign.html
9+
-- See main.c for an example of a wrapper application.
10+
11+
--library vunit_lib;
12+
--context vunit_lib.vunit_context;
13+
14+
library vunit_lib;
15+
use vunit_lib.run_pkg.all;
16+
use vunit_lib.logger_pkg.all;
17+
use vunit_lib.types_pkg.all;
18+
use vunit_lib.byte_vector_ptr_pkg.all;
19+
20+
entity tb_extcp_byte_vector is
21+
generic ( runner_cfg : string );
22+
end entity;
23+
24+
architecture tb of tb_extcp_byte_vector is
25+
26+
constant block_len : natural := 10;
27+
28+
constant ebuf: byte_vector_ptr_t := new_byte_vector_ptr( block_len, extfnc, 0); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
29+
constant abuf: byte_vector_ptr_t := new_byte_vector_ptr( block_len, extacc, 1); -- external through access (requires VHPIDIRECT function 'get_string_ptr')
30+
31+
begin
32+
33+
main: process
34+
variable val: integer;
35+
begin
36+
test_runner_setup(runner, runner_cfg);
37+
info("Init test");
38+
for x in 0 to block_len-1 loop
39+
val := get(ebuf, x);
40+
set(abuf, x, val);
41+
info("SET " & to_string(x) & ": " & to_string(val));
42+
end loop;
43+
info("End test");
44+
test_runner_cleanup(runner);
45+
wait;
46+
end process;
47+
48+
end architecture;
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+
-- NOTE: This file is expected to be used along with foreign languages (C)
8+
-- through VHPIDIRECT: https://ghdl.readthedocs.io/en/latest/using/Foreign.html
9+
-- See main.c for an example of a wrapper application.
10+
11+
--library vunit_lib;
12+
--context vunit_lib.vunit_context;
13+
14+
library vunit_lib;
15+
use vunit_lib.run_pkg.all;
16+
use vunit_lib.logger_pkg.all;
17+
use vunit_lib.types_pkg.all;
18+
use vunit_lib.string_ptr_pkg.all;
19+
20+
entity tb_extcp_string is
21+
generic ( runner_cfg : string );
22+
end entity;
23+
24+
architecture tb of tb_extcp_string is
25+
26+
constant block_len : natural := 10;
27+
28+
constant ebuf: string_ptr_t := new_string_ptr( block_len, extfnc, 0); -- external through VHPIDIRECT functions 'read_char' and 'write_char'
29+
constant abuf: string_ptr_t := new_string_ptr( block_len, extacc, 1); -- external through access (requires VHPIDIRECT function 'get_string_ptr')
30+
31+
begin
32+
33+
main: process
34+
variable val: character;
35+
begin
36+
test_runner_setup(runner, runner_cfg);
37+
info("Init test");
38+
for x in 1 to block_len loop
39+
val := get(ebuf, x);
40+
set(abuf, x, val);
41+
info("SET " & to_string(x) & ": " & to_string(val));
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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ def test_vhdl_axi_dma_example_project(self):
123123
)
124124
def test_vhdl_external_buffer_project(self):
125125
self.check(join(ROOT, "examples", "vhdl", "external_buffer", "run.py"))
126+
self.check(join(ROOT, "examples", "vhdl", "external_buffer", "cp.py"))
126127

127128
def test_vhdl_user_guide_example_project(self):
128129
self.check(join(ROOT, "examples", "vhdl", "user_guide", "run.py"), exit_code=1)

0 commit comments

Comments
 (0)