2

我有一种情况,我有 2 个 C 函数。这些 C 函数有许多错误检查场景,我使用 exit(1) 来逃避。系统 verilog 代码中的一百万个位置通过 DPI 调用调用这 2 个 C 函数。

我在我的 C 例程中使用了 execinfo.h 和 backtrace() 函数,但堆栈跟踪信息显示了 C 函数,但在此之上它只显示了一些随机 vcs_exe.sim.1234_1.so 作为主调用程序函数。

我什至尝试在已发布区域中查找此 vcs_exe.sim.1234.so,但它不指向任何已知的 Sv 文件。

那么,在显示堆栈跟踪时如何获取调用方非 C/SV 函数?

4

3 回答 3

1

理想情况下,您的模拟器会有一个指南,向您展示如何执行此操作。这可能涉及更改构建脚本中的内容以提供额外的可见性。如果您在手册中找不到任何相关内容,供应商的支持部门应该能够为您提供帮助。

如果您的工具不允许这样做,您可以尝试自己实现一些东西。如果您的 DPI 方法是上下文,您可以使用svScope概念来找出调用者信息。我还没有测试它,但它应该是这样的:

svScope scope;
scope = svGetScope();

char *fileName, *lineNumber;
scope.svGetCallerInfo(fileName, lineNumber);

这假设svGetCallerInfo(...)返回 true,我猜它应该用于上下文DPI 方法。

于 2017-08-07T09:44:37.483 回答
0

如何更改 C 代码使其不会退出 (1),而只是打印错误消息并优雅地返回 SV 域?

您需要调试问题的是在打印出错误消息的行处设置一个断点,然后逐步回到模拟器中的 SV 域。瞧!现在不仅知道哪个 SV 类对象调用了 C-DPI,还可以查看 SV 类对象的局部变量来帮助诊断问题。

于 2017-08-13T06:11:32.713 回答
0

它对我使用 vcs 的方式是调用一个导出的函数,该函数将依次调用 $stack。在此示例中,它适用于“默认”和“纯”绑定。

import "DPI-C" context function void testStack();

export "DPI-C" function printStack;

function void printStack;
   $display("====%m=====");

   $stack;
endfunction

module dpis;
   sub sub();
endmodule // dpis

module sub;
   initial
     testStack();
endmodule // sub

class Test;
   function void test;
      testStack();
   endfunction // test
endclass // Abc

program abc;
   Test a = new;
   initial
     a.test();
endprogram // abc

和'c':

#include <svdpi.h>

extern void pringStack();

void testStack() {
    svScope scope;
    scope = svGetScopeFromName("$unit");
    svSetScope(scope);
    printStack();
}

结果如下所示:

====$unit::printStack=====
#0 in printStack at dpis.sv:9
#1 in DPI function
#2 in dpis.sub
====$unit::printStack=====
#0 in printStack at dpis.sv:9
#1 in DPI function
#2 in <protected code>
#3 in abc at dpis.sv:30
#4 in abc

因此,它以模块实例路径或文件/行号的形式提供了有关位置的一些信息。

于 2017-08-07T14:15:01.270 回答