system verilog - How to Pass array from C to SV using SV-DPI? -
my objective pass array c sv , print array contents in sv, have tried following c program of converting text file(data_file.txt) (given full source in link below) array , trying read array using dpi calls in systemveilog(sv), in "c" have passed array values function(mydisplay) inside main func.(please correct me if wrong here) seems array values not read sv environment expect reason, there efficient way array in sv?
c code:
void mydisplay(svopenarrayhandle h) { int *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]; } } sv code:
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 source @ edaplayground
after trials i've found solution , able pass processed text data c sv small tweak, imported function , called exported function using available context method in sv-dpi per lrm, used user defined function , removed main native "c" lang., way able read values in array values c sv, provided below code samples, updated code @ edaplayground
c code:
#include <stdio.h> #include <stdlib.h> /* strtol */ #include <string.h> /* strchr */ #include <limits.h> /* int_min/int_max */ #include <errno.h> /* 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 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 number */ while (errno == 0) { /* skip non-digit characters */ if (!(p = strchr (p, 'x'))) break; strncpy (digits, ++p, 2); digits[2] = 0; /* nul-terminate */ /* convert string number */ values[idx++] = (unsigned)xstrtoul (digits, &ep, base); if (errno || idx == maxl) { /* check error */ fprintf (stderr, "warning: maxl values reached.\n"); break; } p += 2; } } if (fp != stdin) fclose (fp); /* print results */ (i = 0; < idx; i++) { printf ("c values[%2zu] : 0x%02x\t", i, values[i]); v[d]=values[i]; sd = dv(v[d]); } return(sd); } /** string unsigned long error checking */ unsigned long xstrtoul (char *p, char **ep, int base) { errno = 0; unsigned long tmp = strtoul (p, ep, base); /* check 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 found\n"); exit (exit_failure); } return tmp; } sv code:
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
Comments
Post a Comment