输出开放数组作为DPI-C中的形式参数

时间:2017-12-22 18:20:50

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

我有C代码(预测模型),可以生成一个可变长度的数组作为结果。在调用C代码之前不知道这个数组的大小是多少,并且涉及一些随机化(噪声建模)

我需要从SystemVerilog调用这个C预测模型,然后返回输出结果数组。

作为DPI-C的新手,我遇到了3个限制:

  1. 需要在之前分配SV侧的结果数组 调用C代码。因为我不知道它的大小,我 有机会进行分配或不合作。
  2. 我无法从C传递开放数组 - > SV在导出功能中。
  3. 导出函数不能用于类方法(!)
  4. 为了解决这个问题,我在2个接口和全局变量/任务之间创建了一个hacky杂乱。

    我已经发布了我的解决方案并且工作正常,但我想知道是否有人有比这更优雅的解决方案。我特别不喜欢使用全局变量。

    SV:

    export "DPI-C" function allocate_mem;
    export "DPI-C" function set_item;
    import "DPI-C" context function void predictForMe (input int noiseA, input int noiseB);
    
    int result[];
    
    function void allocate_mem(int size);
      result = new[size];
    endfunction
    
    function void set_item(int index, int item);
      result[index] = item;
    endfunction
    
    class my_class;
      // constructor etc etc - assume is valid
    
      // my_func
      function void my_func();
        int noiseA = 10; // hardcode to simplify example
        int noiseB = 20; // hardcode to simplify example
    
        // call imported function
        predictForMe( noiseA, noiseB );
      endfunction
    endclass
    

    C:

    extern void allocate_mem(int size);
    extern void set_item(int index, int item);
    
    void predictForMe(int noiseA, int noiseB)
    {
      // do some calcualation based on noiseA and noiseB
      // generates an answer_array with num elements = X
    
      allocate_mem(X);
      for(i = 0; i < X; i++) set_item(i, answer_array[i]);
    
    }
    

    欢迎任何更好的解决方案。

1 个答案:

答案 0 :(得分:0)

您无法从C代码传递开放数组,因为C代码不知道如何分配这样的数据结构。我想这是因为如果在C代码中分配的数组与SV侧的数组类型不匹配会有问题。例如,假设您在SV端定义了一个100元素固定大小的数组,并且您尝试从C传递一个10元素数组。它也可能很难在C端指定一个可以分配一个函数的函数。 SV阵列数据结构。尺寸和布局不仅取决于元素的数量,还取决于元素的类型。

但是,可以将已分配的数组作为输出参数传递。但是,您必须知道要预分配的元素数量。正如@NominaAnimal建议的那样,你必须通过单独的函数调用传递你将从C接收的元素数量:

dialog_login.xml

在C端,您可以使用import "DPI-C" function int get_num_elems(args...); import "DPI-C" function void get_elems(output int elems, args...); class some_class; function void some_func(); int result[]; // not a global variable result = new[get_num_elems(args...)]; get_elems(result, args...); endfunction endclass 获取指向传入的svGetArrElemPtr1(...)数组的每个元素的指针,并相应地更新它。您可以这样做,因为类型为result,并且两种语言的表示形式相同:

int