How to get dimensions of a verilog vector port using PLI routines?

与世无争的帅哥 提交于 2019-12-24 18:16:12

问题


How can I fetch the dimensions of a vector port using the vpi PLI routines? For example, for the vector port declaration "output [2:1] out;", how can I get the left dimension as 2 and right dimension as 1? I tried using vpiRange property but it seems that vpiRange property is not supported for Ports. Thanks! Putting the code here for clarity.

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];
}

I am getting -1 from vpi_get(vpiLeft/RightRange) as well as in ldim and rdim. Is there anything erroneos with my code?


回答1:


Your problem is that both vpiLeftRange and vpiRightRange return vpiHandle, not the value. When you instantiate a module. They could be constant expressions, or variable index expressions (for highcon). so, you can try to get values for them. Here is an example which works for vcs.

the verilog module looks like this:

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-code is here

#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)); 

    }
}

here is the result

child pvpi.child_inst
   1 pvpi.child_inst.a [3:0]/[3:0]
   1 pvpi.child_inst.b [7:6]/[1:2]

This should work for simple constant expressions with parameters and literals.



来源:https://stackoverflow.com/questions/48975214/how-to-get-dimensions-of-a-verilog-vector-port-using-pli-routines

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!