You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Verilator仿真的C++测试台中用VPI读取指定地址内存值?

实现思路

1. Verilator编译配置

要让仿真支持VPI接口并暴露SRAM数组,编译时必须添加以下关键选项:

  • --vpi:启用VPI接口支持
  • --public-flat-rw:确保/*verilator public*/修饰的数组能被直接访问,简化层级查找
    编译命令示例:
verilator --cc --trace --vpi --public-flat-rw top_module.sv --exe testbench.cpp

2. 两种实现方式

方式一:直接访问Verilator生成的公共成员(推荐,更高效)

因为你已经给sram数组加了/*verilator public*/,Verilator会将其作为SRAM实例模块的公共成员变量暴露,无需VPI即可直接在C++测试台中访问:

// 假设顶层模块为Vtop,SRAM实例名为tc_sram_inst
uint32_t read_sram_direct(Vtop* top, uint32_t addr) {
    // 直接访问数组元素,addr需在0~NumWords-1范围内
    return top->tc_sram_inst->sram[addr];
}

在仿真循环中调用:

int main(int argc, char** argv) {
    Verilated::commandArgs(argc, argv);
    Vtop* top = new Vtop;

    while (!Verilated::gotFinish()) {
        top->clk = !top->clk;
        top->eval();

        // 按需读取地址0x20的值
        if (top->clk == 1) {
            uint32_t data = read_sram_direct(top, 0x20);
            printf("SRAM addr 0x20 value: 0x%08x\n", data);
        }
    }

    delete top;
    return 0;
}

方式二:通过VPI接口访问(适合动态层级查找场景)

如果需要跨层级动态定位SRAM,可使用VPI接口实现:

2.1 包含必要头文件

#include <vpi_user.h>
#include <verilated_vpi.h>

2.2 编写VPI读取函数

uint32_t read_sram_vpi(uint32_t addr) {
    // 按分层路径查找SRAM数组句柄,需替换为实际层级路径(如top.tc_sram_inst.sram)
    vpiHandle sram_handle = vpi_handle_by_name("top.tc_sram_inst.sram", NULL);
    if (!sram_handle) {
        vpi_printf("Error: SRAM handle not found\n");
        return 0;
    }

    // 设置数组索引(即目标地址)
    vpiIndexInfo index_info;
    index_info.index = addr;
    index_info.next = NULL;

    // 获取指定地址的值,根据data_t类型选择格式(宽位向量用vpiVectorVal)
    s_vpi_value value;
    value.format = vpiIntVal;
    vpi_get_value(sram_handle, &value, &index_info);

    return value.value.integer;
}

2.3 仿真中调用VPI函数

int main(int argc, char** argv) {
    Verilated::commandArgs(argc, argv);
    VerilatedVpi::callCbs(vpiStartOfSimulation); // 初始化VPI环境

    Vtop* top = new Vtop;

    while (!Verilated::gotFinish()) {
        top->clk = !top->clk;
        top->eval();

        if (top->clk == 1) {
            uint32_t data = read_sram_vpi(0x10);
            printf("SRAM addr 0x10 value: 0x%08x\n", data);
        }
    }

    VerilatedVpi::callCbs(vpiEndOfSimulation);
    delete top;
    return 0;
}

注意事项

  • 访问地址必须在0~NumWords-1范围内,避免越界
  • 若data_t是宽位向量(如64位),需将value.format改为vpiVectorVal,并处理向量的高低位数据
  • 编译时需通过make -j -f Vtop.mk完成完整编译链接

内容的提问来源于stack exchange,提问作者Sarah_lan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 17:32:47