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+ An array of type uint8_t is allocated and some values are written to the first 1/3
8+ positions. 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_ext_byte_vector.vhd or tb_ext_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 = 5 ;
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+ for (j = 0 ; j < 3 ; j ++ ) {
33+ k += j ;
34+ for (i = 0 ; i < length ; i ++ ) {
35+ z = (length * j )+ i ;
36+
37+ expected = (i + 1 )* 11 + k ;
38+ got = D [0 ][z ];
39+ if (expected != got ) {
40+ printf ("check error %d: %d %d\n" , z , expected , got );
41+ exit (1 );
42+ }
43+ printf ("%d: %d\n" , z , got );
44+ }
45+ }
46+ free (D [0 ]);
47+ }
48+
49+ // Main entrypoint of the application
50+ int main (int argc , char * * argv ) {
51+ // Allocate a buffer which is three times the number of values
52+ // that we want to copy/modify
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+ // Initialize the first 1/3 of the buffer
59+ int i ;
60+ for (i = 0 ; i < length ; i ++ ) {
61+ D [0 ][i ] = (i + 1 )* 11 ;
62+ }
63+ // Print all the buffer
64+ for (i = 0 ; i < 3 * length ; i ++ ) {
65+ printf ("%d: %d\n" , i , D [0 ][i ]);
66+ }
67+
68+ // Register a function to be called when GHDL exits
69+ atexit (exit_handler );
70+
71+ // Start the simulation
72+ return ghdl_main (argc , argv );
73+ }
74+
75+ // External through access (mode<0)
76+
77+ void set_string_ptr (uint8_t id , uint8_t * p ) {
78+ //printf("C set_string_ptr(%d, %p)\n", id, p);
79+ D [id ] = p ;
80+ }
81+
82+ uintptr_t get_string_ptr (uint8_t id ) {
83+ //printf("C get_string_ptr(%d): %p\n", id, D[id]);
84+ return (uintptr_t )D [id ];
85+ }
86+
87+ // External through functions (mode>0)
88+
89+ void write_char (uint8_t id , uint32_t i , uint8_t v ) {
90+ //printf("C write_char(%d, %d): %d\n", id, i, v);
91+ D [id ][i ] = v ;
92+ }
93+
94+ uint8_t read_char (uint8_t id , uint32_t i ) {
95+ //printf("C read_char(%d, %d): %d\n", id, i, D[id][i]);
96+ return D [id ][i ];
97+ }
0 commit comments