如何使用SV-DPI将数组从C传递到SV?

时间:2017-07-28 15:43:56

标签: c system-verilog system-verilog-dpi

我的目标是将数组从C传递到SV并在SV中打印数组内容,我尝试了以下C程序将一些文本文件(data_file.txt)(在下面的链接中给出完整源代码)转换为数组并试图通过在SystemVeilog(SV)中使用DPI调用来回读数组,在“C”中我将数组值传递给我的函数(mydisplay),它位于主函数内部。(如果我错了,请纠正我)似乎数组值也没有被读回SV环境,因为我预期可能是什么原因,是否有一种有效的方法来恢复SV中的数组?

c code:

 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];
    }   
  }   

sv代码:

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 个答案:

答案 0 :(得分:0)

经过一些试验后,我终于找到了解决方案并能够通过一个小小的调整将处理后的文本数据从C传递到SV,我刚刚导入了一个函数并使用SV-DPI中已有的上下文方法调用了导出函数根据LRM,也只使用用户定义的函数并从原生“C”语言中删除了main。这样我就能够读回数组值中从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