Как получить размеры векторного порта verilog, используя процедуры PLI?
Как я могу получить размеры векторного порта, используя подпрограммы vpi PLI? Например, для объявления векторного порта "output [2:1] out;", как я могу получить левое измерение как 2 и правое измерение как 1? Я пытался использовать свойство vpiRange, но кажется, что свойство vpiRange не поддерживается для портов. Спасибо! Выкладываю код здесь для наглядности.
vpiHandle lowconn = vpi_handle(vpiLowConn, portH);
int dim = 0;
int ldim[10];
int rdim[10];
vpiHandle range_itr = vpi_iterate(vpiRange, lowconn );
vpiHandle range;
while ((range = vpi_scan(range_itr))) {
ldim[dim] = vpi_get(vpiLeftRange, range);
rdim[dim] = vpi_get(vpiRightRange, range);
dim++;
}
int size = vpi_get(vpiSize, portH);
cout << endl << vpi_get_str(vpiName, portH) << " size = " << size << " LeftRange = " << vpi_get(vpiLeftRange, lowconn ) << " RightRange = " << vpi_get(vpiRightRange, lowconn );
for ( int i = 0; i < dim; i++ ) {
cout << vpi_get_str(vpiName, portH) << " = " << ldim[i] << ":" << rdim[i];
}
Я получаю -1 от vpi_get(vpiLeft/RightRange), а также в ldim и rdim. Что-нибудь не так с моим кодом?
1 ответ
Ваша проблема заключается в том, что vpiLeftRange и vpiRightRange возвращают vpiHandle, а не значение. Когда вы создаете экземпляр модуля. Это могут быть константные выражения или выражения переменных переменных (для highcon). Итак, вы можете попытаться получить значения для них. Вот пример, который работает для VCS.
модуль verilog выглядит так:
module pvpi (pa, pb);
input wire [3:0] pa;
input wire [7:6] pb;
child child_inst(.a(pa), .b(pb));
initial $report_ports;
endmodule
module child(input [4:1] a, input [1:2] b);
endmodule // child
C-код здесь
#include "vpi_user.h"
static int getExprValue(vpiHandle conn, int r) {
vpiHandle expr = vpi_handle(r, conn);
s_vpi_value val = {vpiIntVal};
vpi_get_value(expr, &val);
return val.value.integer;
}
void report_ports() {
vpiHandle moduleInst = vpi_handle_by_name("pvpi.child_inst", 0);
vpiHandle ports = vpi_iterate(vpiPort, moduleInst);
vpiHandle port;
vpi_printf("%s %s\n", vpi_get_str(vpiDefName, moduleInst), vpi_get_str(vpiFullName, moduleInst));
while ((port = vpi_scan(ports))) {
vpiHandle highConn = vpi_handle(vpiHighConn, port);
vpiHandle lowConn = vpi_handle(vpiLowConn, port);
vpi_printf(" %d %s [%d:%d]/[%d:%d]\n", vpi_get(vpiDirection, port), vpi_get_str(vpiFullName, port),
getExprValue(highConn, vpiLeftRange), getExprValue(highConn, vpiRightRange),
getExprValue(lowConn, vpiLeftRange), getExprValue(lowConn, vpiRightRange));
}
}
вот результат
child pvpi.child_inst
1 pvpi.child_inst.a [3:0]/[3:0]
1 pvpi.child_inst.b [7:6]/[1:2]
Это должно работать для простых константных выражений с параметрами и литералами.