如何在SystemVerilog + C DPI调用的情况下堆栈跟踪信息?

时间:2017-08-06 22:16:53

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

我的情况是我有2个C功能。这些C函数有许多错误检查方案,我使用exit(1)来删除。系统verilog代码中有一百万个位置通过DPI调用调用这两个C函数。

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

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

那么,如何在显示堆栈跟踪时获得调用者非C / SV功能?

3 个答案:

答案 0 :(得分:1)

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

如果您的工具不允许这样做,您可以尝试自己实施。如果您的DPI方法是上下文,则可以使用 svScope 概念来确定调用者信息。我还没有对它进行测试,但它应该是这样的:

./MyFile.sh 123 ABC000987

这假设svScope scope; scope = svGetScope(); char *fileName, *lineNumber; scope.svGetCallerInfo(fileName, lineNumber); 返回true,我认为它应该用于 context DPI方法。

答案 1 :(得分:0)

使用vcs对我有用的方法是调用一个导出的函数,该函数将轮流调用$ stack。在这个例子中,它适用于'default'和'pure'绑定。

slot=<slotname>

和'c':

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

,结果如下:

#include <svdpi.h>

extern void pringStack();

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

因此,它提供了有关位置的一些信息,可以是模块实例路径,也可以是文件/文件。

答案 2 :(得分:0)

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

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