Как передать массив из C в SV, используя SV-DPI?
Моя цель - передать массив из C в SV и распечатать содержимое массива в SV. Я попробовал следующую программу на C: преобразовать какой-нибудь текстовый файл (data_file.txt) (с полным исходным кодом в ссылке ниже) в массив и попробовать чтобы прочитать массив с помощью вызовов DPI в SystemVeilog(SV), в "C" я передал значения массива в свою функцию (mydisplay), которая находится внутри основного функционала (пожалуйста, исправьте меня, если я здесь не прав), также кажется, что значения массива не считываются обратно в среду SV, как я и ожидал, в чем может быть причина, существует ли эффективный способ вернуть массив в SV?
код c:
void mydisplay(svOpenArrayHandle h) {
int *a;
a =(int*)svGetArrayPtr(h);
for( i=0;i<idx;i++) {
io_printf("C: values[%2zu]=0x%02x\n",i,values[i]);
a[i] = values[i];
}
}
св код:
program automatic top;
int a[32000];
import "DPI-C" function void mydisplay(inout int h[]);
initial begin
mydisplay(a);
foreach(a[i]) $display("SV after DPI: a[%0d]=%0d",i,a[i]);
end
endprogram
источник на EDAplayground
1 ответ
После некоторых испытаний я наконец нашел решение и смог передать обработанные текстовые данные из C в SV с помощью небольшого изменения. Я просто импортировал функцию и вызвал экспортированную функцию, используя уже доступный метод контекста в SV-DPI согласно LRM., также использовал только определенную пользователем функцию и удалил основную из родного языка "C". Таким образом, я смог прочитать значения в массиве значений от C до SV, предоставленные ниже примеры кода, обновленный код на EDAPlayground
Код C:
#include <stdio.h>
#include <stdlib.h> /* for strtol */
#include <string.h> /* for strchr */
#include <limits.h> /* for INT_MIN/INT_MAX */
#include <errno.h> /* for errno */
extern int dV(int r);
#define MAXL 50000
unsigned long xstrtoul (char *p, char **ep, int base);
int mydisplay()
{
int v[15];
int sd;
int d;
FILE *fp = fopen ("data_file.txt", "r");
char line[MAXL] = {0};
unsigned values[MAXL] = {0};
int base = 16;
size_t i, idx = 0;
if (!fp) { /* validate file open */
fprintf (stderr, "error: file open failen '%s'.\n", fp);
return 1;
}
/* read each line in file (up to MAXL chars per-line) */
while (fgets (line, MAXL, fp)) {
char *p = line;
char *ep = p;
char digits[3] = {0};
errno = 0;
/* convert each string of digits into number */
while (errno == 0) {
/* skip any non-digit characters */
if (!(p = strchr (p, 'x'))) break;
strncpy (digits, ++p, 2);
digits[2] = 0; /* nul-terminate */
/* convert string to number */
values[idx++] = (unsigned)xstrtoul (digits, &ep, base);
if (errno || idx == MAXL) { /* check for error */
fprintf (stderr, "warning: MAXL values reached.\n");
break;
}
p += 2;
}
}
if (fp != stdin) fclose (fp);
/* print results */
for (i = 0; i < idx; i++)
{
printf ("C values[%2zu] : 0x%02x\t", i, values[i]);
v[d]=values[i];
sd = dV(v[d]);
}
return(sd);
}
/** string to unsigned long with error checking */
unsigned long xstrtoul (char *p, char **ep, int base)
{
errno = 0;
unsigned long tmp = strtoul (p, ep, base);
/* Check for various possible errors */
if ((errno == ERANGE && (tmp == ULONG_MAX)) ||
(errno != 0 && tmp == 0)) {
perror ("strtoul");
exit (EXIT_FAILURE);
}
if (*ep == p) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}
return tmp;
}
Код SV:
program automatic top();
int res;
import "DPI" context mydisplay= function int mD();
export "DPI" dV =function mydisplay;
function int mydisplay(input int xyz);
$display ("SV after DPI: %0d\n",xyz);
return -1;
endfunction
initial begin
#5 res=mD();
$display("Finished reading values...\n");
end
endprogram