Как я собираю информацию трассировки в случае вызовов SystemVerilog+C DPI?

У меня есть ситуация, когда у меня есть 2 функции C. Эти функции C имеют много сценариев проверки ошибок, где я использую выход (1), чтобы справиться с ситуацией. Миллион мест в системном коде verilog вызывает эти 2 C-функции через вызовы DPI.

Я использовал функции execinfo.h и backtrace() в своих подпрограммах C, но информация трассировки стека отображает функцию C, но выше она просто показывает некоторый случайный vcs_exe.sim.1234_1.so в качестве основной функции вызова.

Я даже пытался найти этот vcs_exe.sim.1234.so в опубликованной области, но он не указывает ни на какой известный файл Sv.

Итак, как я могу получить функцию вызывающего не-C/SV, когда отображается трассировка стека?

3 ответа

В идеале у вашего симулятора должно быть руководство, показывающее, как это сделать. Это может потребовать изменения материала в вашем скрипте сборки, чтобы обеспечить дополнительную видимость. Отдел поддержки поставщика должен быть в состоянии помочь вам, если вы не можете найти что-либо об этом в руководстве.

Если ваш инструмент не позволяет этого, вы можете попробовать реализовать что-то самостоятельно. Если ваш метод DPI является контекстным, вы можете использовать концепцию svScope, чтобы выяснить информацию о вызывающем абоненте. Я не проверял это, но это должно быть что-то вроде:

svScope scope;
scope = svGetScope();

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

Это предполагает, что svGetCallerInfo(...) вернул true, что, я думаю, должно быть для методов контекста DPI.

Как насчет изменения кода C, чтобы он не выходил из (1), вместо этого он просто распечатывает сообщение об ошибке и корректно возвращается в SV-домен?

Для отладки проблемы вам нужно установить точку останова на строке, которая выводит сообщение об ошибке, а затем вернуться в SV-домен в симуляторе. Вуаля! Теперь вы не только знаете, какой объект класса SV вызывает C-DPI, вы можете видеть локальные переменные объекта класса SV, чтобы помочь диагностировать проблему.

Я работал с vcs так, чтобы он вызывал экспортированную функцию, которая в свою очередь вызывала бы стек $. Это работает для меня с привязкой 'default' и 'pure' в этом примере.

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

Таким образом, он дает некоторую информацию о местоположении либо в виде пути к экземпляру модуля, либо в виде файла / белья.

Другие вопросы по тегам