Verilog 使用Verilator和VPI读取REG数组

Verilog 使用Verilator和VPI读取REG数组,verilog,verilator,vpi,Verilog,Verilator,Vpi,所以我在verilog中定义了以下寄存器 reg [31:0] register_mem [0:15]/* verilator public */; 我的目标是从我的VielC++ C++代码中读取每个存储在其中的16个值。 我发现这个VPI的文档很难找到。我仍然不知道什么是tvpi_vecval及其参数是什么,或者它是否是正确的方法 下面是我读取寄存器中第5个值的方法 unsigned int read_regs() { const std::string path = "TOP.T

所以我在verilog中定义了以下寄存器

reg [31:0] register_mem [0:15]/* verilator public */;
我的目标是从我的VielC++ C++代码中读取每个存储在其中的16个值。 我发现这个VPI的文档很难找到。我仍然不知道什么是
tvpi_vecval
及其参数是什么,或者它是否是正确的方法

下面是我读取寄存器中第5个值的方法

unsigned int read_regs() {
    const std::string path = "TOP.TOP.cpu.reg_file.register_mem";
    vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)path.c_str(), NULL);
    if (!vh1) { 
        printf("Name %s", path.c_str());
        vl_fatal(__FILE__, __LINE__, "sim_main", "No handle found: ");
    }
    const char* name = vpi_get_str(vpiName, vh1);


    s_vpi_value v;
    v.format = vpiVectorVal;
    vpi_get_value(vh1, &v);
    return v.value.vector[4].aval;
}
无论我在这里做什么,该方法都返回0,表明我没有查看寄存器\ u mem数组


我做错了什么?

为了获取数组的值,需要分别获取数组中每个元素的值。VPI不返回完整数组的值

实际上,数组的句柄是
vpiregaray
类型的句柄。它可以迭代访问每个单独的元素

下面是一个简单的代码,它执行迭代并打印数组中每个元素的值:


#include "vpi_user.h"

PLI_INT32 preg_calltf( char *txt ) {
    vpiHandle hreg = vpi_handle_by_name("rarr.register_mem", 0);
    vpi_printf("reg type: %s\n", vpi_get_str(vpiType, hreg)); // vpiRegArray

    s_vpi_value val = {vpiDecStrVal}; // struct t_vpi_value

    vpiHandle arrayIterator = vpi_iterate( vpiReg, hreg); 
    if( arrayIterator != NULL ) {
        vpiHandle item = NULL;
        while( NULL != ( item = vpi_scan( arrayIterator ) ) ) {
            vpi_get_value(item, &val);
            vpi_printf("item type: %s = %s\n", vpi_get_str(vpiType, item), val.value.str); // vpiReg
            vpi_free_object( item );
        }
    }

    return 0;
}
在本例中,我使用
vpiDecStrVal
初始化了
val
。它指示编译器将值结果准备为十进制字符串。现在可以通过
val.value.str
访问该值。您有多种选择来获取以2状态或4状态表示的字符串或二进制数据

对于最多32位的2状态值,可以使用整数格式。但是,对于较长的值或4状态,您需要
vpiVectorVal
。它实际上要求verilog创建两个32位整数数组,aval和bval。两者都有足够大的大小来保存所有的值位。aval和bval中的位组合表示向量中所有位的4状态值


LRM中提供了所有vpi信息,包括关系图和数据结构。还有一些书,例如萨瑟兰的《verilog pli手册》。

不幸的是,这对我不适用。有几件事偏离了方向。打印行报告它是一个
vpiMemory
(如果这意味着它合成为Bram而不是触发器,那么这很好,因为我写它是为了同步访问,所以它将是一个Bram)。但是迭代器对我来说总是空的,所以它永远不会进入循环。该值是否位于主模块的子模块中可能很重要?尝试对迭代器使用
vpiMemoryWord
,而不是
vipReg
Bingo!就是这样!非常感谢!